You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Made dispatching of sync events more consistent
This commit is contained in:
		| @@ -4,6 +4,7 @@ import { _ } from 'lib/locale.js'; | ||||
| import { Setting } from 'lib/models/setting.js'; | ||||
| import { BaseItem } from 'lib/models/base-item.js'; | ||||
| import { vorpalUtils } from './vorpal-utils.js'; | ||||
| import { Synchronizer } from 'lib/synchronizer.js'; | ||||
| const locker = require('proper-lockfile'); | ||||
| const fs = require('fs-extra'); | ||||
|  | ||||
| @@ -74,7 +75,7 @@ class Command extends BaseCommand { | ||||
|  | ||||
| 			let options = { | ||||
| 				onProgress: (report) => { | ||||
| 					let lines = sync.reportToLines(report); | ||||
| 					let lines = Synchronizer.reportToLines(report); | ||||
| 					if (lines.length) vorpalUtils.redraw(lines.join(' ')); | ||||
| 				}, | ||||
| 				onMessage: (msg) => { | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { Log } from 'lib/log.js'; | ||||
| import { Note } from 'lib/models/note.js'; | ||||
| import { FoldersScreenUtils } from 'lib/components/screens/folders-utils.js' | ||||
| import { NotesScreenUtils } from 'lib/components/screens/notes-utils.js' | ||||
| import { Synchronizer } from 'lib/synchronizer.js'; | ||||
| import { reg } from 'lib/registry.js'; | ||||
| import { _ } from 'lib/locale.js'; | ||||
|  | ||||
| @@ -65,37 +66,22 @@ class SideMenuContentComponent extends Component { | ||||
| 		NotesScreenUtils.openNoteList(folder.id); | ||||
| 	} | ||||
|  | ||||
| 	async synchronizer_progress(report) { | ||||
| 		const sync = await reg.synchronizer(); | ||||
| 		let lines = sync.reportToLines(report); | ||||
| 		this.setState({ syncReportText: lines.join("\n") }); | ||||
| 	} | ||||
|  | ||||
| 	synchronizer_complete() { | ||||
| 		FoldersScreenUtils.refreshFolders(); | ||||
| 	} | ||||
|  | ||||
| 	async componentWillMount() { | ||||
| 		reg.dispatcher().on('synchronizer_progress', this.synchronizer_progress.bind(this)); | ||||
| 		reg.dispatcher().on('synchronizer_complete', this.synchronizer_complete.bind(this)); | ||||
| 	} | ||||
|  | ||||
| 	componentWillUnmount() { | ||||
| 		reg.dispatcher().off('synchronizer_progress', this.synchronizer_progress.bind(this)); | ||||
| 		reg.dispatcher().off('synchronizer_complete', this.synchronizer_complete.bind(this)); | ||||
| 	} | ||||
|  | ||||
| 	async synchronize_press() { | ||||
| 		if (reg.oneDriveApi().auth()) { | ||||
| 			const sync = await reg.synchronizer() | ||||
| 			sync.start(); | ||||
| 		const sync = await reg.synchronizer() | ||||
|  | ||||
| 		if (this.props.syncStarted) { | ||||
| 			sync.cancel(); | ||||
| 		} else { | ||||
| 			this.props.dispatch({ type: 'SIDE_MENU_CLOSE' }); | ||||
| 			 | ||||
| 			this.props.dispatch({ | ||||
| 				type: 'Navigation/NAVIGATE', | ||||
| 				routeName: 'OneDriveLogin', | ||||
| 			}); | ||||
| 			if (reg.oneDriveApi().auth()) {		 | ||||
| 				sync.start(); | ||||
| 			} else { | ||||
| 				this.props.dispatch({ type: 'SIDE_MENU_CLOSE' }); | ||||
| 				 | ||||
| 				this.props.dispatch({ | ||||
| 					type: 'Navigation/NAVIGATE', | ||||
| 					routeName: 'OneDriveLogin', | ||||
| 				}); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -116,9 +102,14 @@ class SideMenuContentComponent extends Component { | ||||
|  | ||||
| 		if (items.length) items.push(<View style={{ height: 50, flex: -1 }} key='divider_1'></View>); // DIVIDER | ||||
|  | ||||
| 		items.push(<Button title="Synchronize" onPress={() => { this.synchronize_press() }} key='synchronize' />); | ||||
| 		const syncTitle = this.props.syncStarted ? 'Cancel sync' : 'Synchronize'; | ||||
|  | ||||
| 		items.push(<Text key='sync_report'>{this.state.syncReportText}</Text>); | ||||
| 		let lines = Synchronizer.reportToLines(this.props.syncReport); | ||||
| 		const syncReportText = lines.join("\n"); | ||||
|  | ||||
| 		items.push(<Button title={syncTitle} onPress={() => { this.synchronize_press() }} key='synchronize' />); | ||||
|  | ||||
| 		items.push(<Text key='sync_report'>{syncReportText}</Text>); | ||||
|  | ||||
| 		return ( | ||||
| 			<ScrollView scrollsToTop={false} style={styles.menu}> | ||||
| @@ -132,6 +123,8 @@ const SideMenuContent = connect( | ||||
| 	(state) => { | ||||
| 		return { | ||||
| 			folders: state.folders, | ||||
| 			syncStarted: state.syncStarted, | ||||
| 			syncReport: state.syncReport, | ||||
| 		}; | ||||
| 	} | ||||
| )(SideMenuContentComponent) | ||||
|   | ||||
| @@ -5,16 +5,9 @@ import { parameters } from 'lib/parameters.js'; | ||||
| import { FileApi } from 'lib/file-api.js'; | ||||
| import { Synchronizer } from 'lib/synchronizer.js'; | ||||
| import { FileApiDriverOneDrive } from 'lib/file-api-driver-onedrive.js'; | ||||
| import { EventDispatcher } from 'lib/event-dispatcher.js'; | ||||
|  | ||||
| const reg = {}; | ||||
|  | ||||
| reg.dispatcher = () => { | ||||
| 	if (this.dispatcher_) return this.dispatcher_; | ||||
| 	this.dispatcher_ = new EventDispatcher(); | ||||
| 	return this.dispatcher_; | ||||
| } | ||||
|  | ||||
| reg.logger = () => { | ||||
| 	if (!reg.logger_) { | ||||
| 		console.warn('Calling logger before it is initialized'); | ||||
| @@ -77,15 +70,7 @@ reg.synchronizer = async () => { | ||||
| 	let fileApi = await reg.fileApi(); | ||||
| 	reg.synchronizer_ = new Synchronizer(reg.db(), fileApi, Setting.value('appType')); | ||||
| 	reg.synchronizer_.setLogger(reg.logger()); | ||||
|  | ||||
| 	reg.synchronizer_.on('progress', (report) => { | ||||
| 		reg.dispatcher().dispatch('synchronizer_progress', report); | ||||
| 	});	 | ||||
|  | ||||
| 	reg.synchronizer_.on('complete', () => { | ||||
| 		reg.dispatcher().dispatch('synchronizer_complete'); | ||||
| 	}); | ||||
|  | ||||
| 	reg.synchronizer_.dispatch = reg.dispatch; | ||||
| 	return reg.synchronizer_; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,6 @@ import { sprintf } from 'sprintf-js'; | ||||
| import { time } from 'lib/time-utils.js'; | ||||
| import { Logger } from 'lib/logger.js' | ||||
| import { _ } from 'lib/locale.js'; | ||||
| import { EventDispatcher } from 'lib/event-dispatcher.js'; | ||||
| import moment from 'moment'; | ||||
|  | ||||
| class Synchronizer { | ||||
| @@ -25,15 +24,7 @@ class Synchronizer { | ||||
| 		this.onProgress_ = function(s) {}; | ||||
| 		this.progressReport_ = {}; | ||||
|  | ||||
| 		this.dispatcher_ = new EventDispatcher(); | ||||
| 	} | ||||
|  | ||||
| 	on(eventName, callback) { | ||||
| 		return this.dispatcher_.on(eventName, callback); | ||||
| 	} | ||||
|  | ||||
| 	off(eventName, callback) { | ||||
| 		return this.dispatcher_.off(eventName, callback); | ||||
| 		this.dispatch = function(action) {}; | ||||
| 	} | ||||
|  | ||||
| 	state() { | ||||
| @@ -56,7 +47,7 @@ class Synchronizer { | ||||
| 		return this.logger_; | ||||
| 	} | ||||
|  | ||||
| 	reportToLines(report) { | ||||
| 	static reportToLines(report) { | ||||
| 		let lines = []; | ||||
| 		if (report.createLocal) lines.push(_('Created local items: %d.', report.createLocal)); | ||||
| 		if (report.updateLocal) lines.push(_('Updated local items: %d.', report.updateLocal)); | ||||
| @@ -66,7 +57,9 @@ class Synchronizer { | ||||
| 		if (report.deleteRemote) lines.push(_('Deleted remote items: %d.', report.deleteRemote)); | ||||
| 		if (report.state) lines.push(_('State: %s.', report.state.replace(/_/g, ' '))); | ||||
| 		if (report.errors && report.errors.length) lines.push(_('Last error: %s (stacktrace in log).', report.errors[report.errors.length-1].message)); | ||||
| 		if (report.cancelling && !report.completedTime) lines.push(_('Cancelling...')); | ||||
| 		if (report.completedTime) lines.push(_('Completed: %s', time.unixMsToLocalDateTime(report.completedTime))); | ||||
|  | ||||
| 		return lines; | ||||
| 	} | ||||
|  | ||||
| @@ -101,7 +94,7 @@ class Synchronizer { | ||||
| 		this.progressReport_.state = this.state(); | ||||
| 		this.onProgress_(this.progressReport_); | ||||
|  | ||||
| 		this.dispatcher_.dispatch('progress', this.progressReport_); | ||||
| 		this.dispatch({ type: 'SYNC_REPORT_UPDATE', report: Object.assign({}, this.progressReport_) }); | ||||
| 	} | ||||
|  | ||||
| 	async logSyncSummary(report) { | ||||
| @@ -141,7 +134,7 @@ class Synchronizer { | ||||
| 	cancel() { | ||||
| 		if (this.cancelling_) return; | ||||
| 		 | ||||
| 		this.logger().info('Cancelling synchronization...'); | ||||
| 		this.logSyncOperation('cancelling', null, null, ''); | ||||
| 		this.cancelling_ = true; | ||||
| 	} | ||||
|  | ||||
| @@ -173,11 +166,13 @@ class Synchronizer { | ||||
|  | ||||
| 		this.state_ = 'in_progress'; | ||||
|  | ||||
| 		this.dispatch({ type: 'SYNC_STARTED' }); | ||||
|  | ||||
| 		this.logSyncOperation('starting', null, null, 'Starting synchronization to ' + this.api().driver().syncTargetName() + ' (' + syncTargetId + ')... [' + synchronizationId + ']'); | ||||
|  | ||||
| 		try { | ||||
| 			await this.api().mkdir(this.syncDirName_); | ||||
| 			await this.api().mkdir(this.resourceDirName_);			 | ||||
| 			await this.api().mkdir(this.resourceDirName_); | ||||
|  | ||||
| 			let donePaths = []; | ||||
| 			while (true) { | ||||
| @@ -442,16 +437,16 @@ class Synchronizer { | ||||
|  | ||||
| 		this.state_ = 'idle'; | ||||
|  | ||||
| 		this.logSyncOperation('finished', null, null, 'Synchronization finished [' + synchronizationId + ']'); | ||||
|  | ||||
| 		this.progressReport_.completedTime = time.unixMs(); | ||||
|  | ||||
| 		this.logSyncOperation('finished', null, null, 'Synchronization finished [' + synchronizationId + ']'); | ||||
|  | ||||
| 		await this.logSyncSummary(this.progressReport_); | ||||
|  | ||||
| 		this.onProgress_ = function(s) {}; | ||||
| 		this.progressReport_ = {}; | ||||
|  | ||||
| 		this.dispatcher_.dispatch('complete'); | ||||
| 		this.dispatch({ type: 'SYNC_COMPLETED' }); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -48,6 +48,8 @@ let defaultState = { | ||||
| 		orderBy: 'updated_time', | ||||
| 		orderByDir: 'DESC', | ||||
| 	}, | ||||
| 	syncStarted: false, | ||||
| 	syncReport: {}, | ||||
| }; | ||||
|  | ||||
| const initialRoute = { | ||||
| @@ -264,6 +266,24 @@ const reducer = (state = defaultState, action) => { | ||||
| 				newState.showSideMenu = false | ||||
| 				break; | ||||
|  | ||||
| 			case 'SYNC_STARTED': | ||||
|  | ||||
| 				newState = Object.assign({}, state); | ||||
| 				newState.syncStarted = true; | ||||
| 				break; | ||||
|  | ||||
| 			case 'SYNC_COMPLETED': | ||||
|  | ||||
| 				newState = Object.assign({}, state); | ||||
| 				newState.syncStarted = false; | ||||
| 				break; | ||||
|  | ||||
| 			case 'SYNC_REPORT_UPDATE': | ||||
|  | ||||
| 				newState = Object.assign({}, state); | ||||
| 				newState.syncReport = action.report; | ||||
| 				break; | ||||
|  | ||||
| 		} | ||||
| 	} catch (error) { | ||||
| 		error.message = 'In reducer: ' + error.message; | ||||
| @@ -307,7 +327,7 @@ async function initialize(dispatch, backButtonHandler) { | ||||
| 	dbLogger.addTarget('database', { database: logDatabase, source: 'm' });  | ||||
| 	if (Setting.value('env') == 'dev') { | ||||
| 		dbLogger.addTarget('console'); | ||||
| 		dbLogger.setLevel(Logger.LEVEL_DEBUG); // Set to LEVEL_DEBUG for full SQL queries | ||||
| 		dbLogger.setLevel(Logger.LEVEL_INFO); // Set to LEVEL_DEBUG for full SQL queries | ||||
| 	} else { | ||||
| 		dbLogger.setLevel(Logger.LEVEL_INFO); | ||||
| 	} | ||||
| @@ -316,6 +336,7 @@ async function initialize(dispatch, backButtonHandler) { | ||||
| 	db.setLogger(dbLogger); | ||||
| 	reg.setDb(db); | ||||
|  | ||||
| 	reg.dispatch = dispatch; | ||||
| 	BaseModel.dispatch = dispatch; | ||||
| 	NotesScreenUtils.dispatch = dispatch; | ||||
| 	NotesScreenUtils.store = store; | ||||
| @@ -332,7 +353,8 @@ async function initialize(dispatch, backButtonHandler) { | ||||
| 		if (Setting.value('env') == 'prod') { | ||||
| 			await db.open({ name: 'joplin.sqlite' }) | ||||
| 		} else { | ||||
| 			await db.open({ name: 'joplin-55.sqlite' }) | ||||
| 			//await db.open({ name: 'joplin-56.sqlite' }) | ||||
| 			await db.open({ name: 'joplin-56.sqlite' }) | ||||
|  | ||||
| 			// await db.exec('DELETE FROM notes'); | ||||
| 			// await db.exec('DELETE FROM folders'); | ||||
| @@ -379,6 +401,11 @@ async function initialize(dispatch, backButtonHandler) { | ||||
|  | ||||
| class AppComponent extends React.Component { | ||||
|  | ||||
| 	constructor() { | ||||
| 		super(); | ||||
| 		this.lastSyncStarted_ = defaultState.syncStarted; | ||||
| 	} | ||||
|  | ||||
| 	async componentDidMount() { | ||||
| 		await initialize(this.props.dispatch, this.backButtonHandler.bind(this)); | ||||
| 		reg.scheduleSync(); | ||||
| @@ -398,6 +425,13 @@ class AppComponent extends React.Component { | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	componentWillReceiveProps(newProps) { | ||||
| 		if (newProps.syncStarted != this.lastSyncStarted_) { | ||||
| 			if (!newProps.syncStarted) FoldersScreenUtils.refreshFolders(); | ||||
| 			this.lastSyncStarted_ = newProps.syncStarted; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	sideMenu_change(isOpen) { | ||||
| 		// Make sure showSideMenu property of state is updated | ||||
| 		// when the menu is open/closed. | ||||
| @@ -433,6 +467,7 @@ const mapStateToProps = (state) => { | ||||
| 	return { | ||||
|   		historyCanGoBack: state.historyCanGoBack, | ||||
|   		showSideMenu: state.showSideMenu, | ||||
|   		syncStarted: state.syncStarted, | ||||
|   	}; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user