You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Clipper: Added Clipper config screen and improved server
This commit is contained in:
		| @@ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
| 	"manifest_version": 2, | 	"manifest_version": 2, | ||||||
| 	"name": "Joplin Web Clipper", | 	"name": "Joplin Web Clipper", | ||||||
| 	"version": "1.0", | 	"version": "1.0.1", | ||||||
|  |  | ||||||
| 	"description": "Gets and saves content from your browser to Joplin.", | 	"description": "Gets and saves content from your browser to Joplin.", | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								Clipper/joplin-webclipper/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										32
									
								
								Clipper/joplin-webclipper/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -4,10 +4,42 @@ | |||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "fs-extra": { | ||||||
|  |       "version": "6.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", | ||||||
|  |       "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "graceful-fs": "^4.1.2", | ||||||
|  |         "jsonfile": "^4.0.0", | ||||||
|  |         "universalify": "^0.1.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "graceful-fs": { | ||||||
|  |       "version": "4.1.11", | ||||||
|  |       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", | ||||||
|  |       "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", | ||||||
|  |       "dev": true | ||||||
|  |     }, | ||||||
|  |     "jsonfile": { | ||||||
|  |       "version": "4.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", | ||||||
|  |       "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", | ||||||
|  |       "dev": true, | ||||||
|  |       "requires": { | ||||||
|  |         "graceful-fs": "^4.1.6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "readability-node": { |     "readability-node": { | ||||||
|       "version": "0.1.0", |       "version": "0.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/readability-node/-/readability-node-0.1.0.tgz", |       "resolved": "https://registry.npmjs.org/readability-node/-/readability-node-0.1.0.tgz", | ||||||
|       "integrity": "sha1-DUBacMLCFZRKf0qbX3UGzQWpsao=" |       "integrity": "sha1-DUBacMLCFZRKf0qbX3UGzQWpsao=" | ||||||
|  |     }, | ||||||
|  |     "universalify": { | ||||||
|  |       "version": "0.1.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", | ||||||
|  |       "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", | ||||||
|  |       "dev": true | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,5 +10,8 @@ | |||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "readability-node": "^0.1.0" |     "readability-node": "^0.1.0" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "fs-extra": "^6.0.1" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ import React, { Component } from 'react'; | |||||||
| import './App.css'; | import './App.css'; | ||||||
|  |  | ||||||
| const { connect } = require('react-redux'); | const { connect } = require('react-redux'); | ||||||
| const Global = require('./Global'); |  | ||||||
| const { bridge } = require('./bridge'); | const { bridge } = require('./bridge'); | ||||||
|  |  | ||||||
| class AppComponent extends Component { | class AppComponent extends Component { | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ import ReactDOM from 'react-dom'; | |||||||
| import './index.css'; | import './index.css'; | ||||||
| import App from './App'; | import App from './App'; | ||||||
|  |  | ||||||
| const { connect, Provider } = require('react-redux'); | const { Provider } = require('react-redux'); | ||||||
| const { bridge } = require('./bridge'); | const { bridge } = require('./bridge'); | ||||||
| const { createStore } = require('redux'); | const { createStore } = require('redux'); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -34,9 +34,6 @@ const reservedPorts = [1024, 1027, 1028, 1029, 1058, 1059, 1080, 1085, 1098, 109 | |||||||
|  |  | ||||||
| // From https://github.com/coverslide/node-alea | // From https://github.com/coverslide/node-alea | ||||||
| const AleaModule = function () { | const AleaModule = function () { | ||||||
|  |  | ||||||
|   'use strict'; |  | ||||||
|  |  | ||||||
|   // importState to sync generator states |   // importState to sync generator states | ||||||
|   Alea.importState = function(i){ |   Alea.importState = function(i){ | ||||||
|     var random = new Alea(); |     var random = new Alea(); | ||||||
| @@ -54,8 +51,8 @@ const AleaModule = function () { | |||||||
|       var s2 = 0; |       var s2 = 0; | ||||||
|       var c = 1; |       var c = 1; | ||||||
|  |  | ||||||
|       if (args.length == 0) { |       if (args.length === 0) { | ||||||
|         args = [+new Date]; |         args = [+new Date()]; | ||||||
|       } |       } | ||||||
|       var mash = Mash(); |       var mash = Mash(); | ||||||
|       s0 = mash(' '); |       s0 = mash(' '); | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ const DecryptionWorker = require('lib/services/DecryptionWorker'); | |||||||
| const InteropService = require('lib/services/InteropService'); | const InteropService = require('lib/services/InteropService'); | ||||||
| const InteropServiceHelper = require('./InteropServiceHelper.js'); | const InteropServiceHelper = require('./InteropServiceHelper.js'); | ||||||
| const ResourceService = require('lib/services/ResourceService'); | const ResourceService = require('lib/services/ResourceService'); | ||||||
|  | const ClipperServer = require('lib/ClipperServer'); | ||||||
|  |  | ||||||
| const { bridge } = require('electron').remote.require('./bridge'); | const { bridge } = require('electron').remote.require('./bridge'); | ||||||
| const Menu = bridge().Menu; | const Menu = bridge().Menu; | ||||||
| @@ -459,6 +460,14 @@ class Application extends BaseApplication { | |||||||
| 				}, { | 				}, { | ||||||
| 					type: 'separator', | 					type: 'separator', | ||||||
| 					screens: ['Main'], | 					screens: ['Main'], | ||||||
|  | 				},{ | ||||||
|  | 					label: _('Web clipper options'), | ||||||
|  | 					click: () => { | ||||||
|  | 						this.dispatch({ | ||||||
|  | 							type: 'NAV_GO', | ||||||
|  | 							routeName: 'ClipperConfig', | ||||||
|  | 						}); | ||||||
|  | 					} | ||||||
| 				},{ | 				},{ | ||||||
| 					label: _('Encryption options'), | 					label: _('Encryption options'), | ||||||
| 					click: () => { | 					click: () => { | ||||||
| @@ -662,6 +671,17 @@ class Application extends BaseApplication { | |||||||
| 				DecryptionWorker.instance().scheduleStart(); | 				DecryptionWorker.instance().scheduleStart(); | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		const clipperLogger = new Logger(); | ||||||
|  | 		clipperLogger.addTarget('file', { path: Setting.value('profileDir') + '/log-clipper.txt' }); | ||||||
|  | 		clipperLogger.addTarget('console'); | ||||||
|  |  | ||||||
|  | 		ClipperServer.instance().setLogger(clipperLogger); | ||||||
|  | 		ClipperServer.instance().setDispatch(this.store().dispatch); | ||||||
|  |  | ||||||
|  | 		if (Setting.value('clipperServer.autoStart')) { | ||||||
|  | 			ClipperServer.instance().start(); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										106
									
								
								ElectronClient/app/gui/ClipperConfigScreen.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								ElectronClient/app/gui/ClipperConfigScreen.jsx
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -13,6 +13,7 @@ const { StatusScreen } = require('./StatusScreen.min.js'); | |||||||
| const { ImportScreen } = require('./ImportScreen.min.js'); | const { ImportScreen } = require('./ImportScreen.min.js'); | ||||||
| const { ConfigScreen } = require('./ConfigScreen.min.js'); | const { ConfigScreen } = require('./ConfigScreen.min.js'); | ||||||
| const { EncryptionConfigScreen } = require('./EncryptionConfigScreen.min.js'); | const { EncryptionConfigScreen } = require('./EncryptionConfigScreen.min.js'); | ||||||
|  | const { ClipperConfigScreen } = require('./ClipperConfigScreen.min.js'); | ||||||
| const { Navigator } = require('./Navigator.min.js'); | const { Navigator } = require('./Navigator.min.js'); | ||||||
|  |  | ||||||
| const { app } = require('../app'); | const { app } = require('../app'); | ||||||
| @@ -86,6 +87,7 @@ class RootComponent extends React.Component { | |||||||
| 			Config: { screen: ConfigScreen, title: () => _('Options') }, | 			Config: { screen: ConfigScreen, title: () => _('Options') }, | ||||||
| 			Status: { screen: StatusScreen, title: () => _('Synchronisation Status') }, | 			Status: { screen: StatusScreen, title: () => _('Synchronisation Status') }, | ||||||
| 			EncryptionConfig: { screen: EncryptionConfigScreen, title: () => _('Encryption Options') }, | 			EncryptionConfig: { screen: EncryptionConfigScreen, title: () => _('Encryption Options') }, | ||||||
|  | 			ClipperConfig: { screen: ClipperConfigScreen, title: () => _('Clipper Options') }, | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 		return ( | 		return ( | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								ElectronClient/app/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								ElectronClient/app/package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -5452,6 +5452,11 @@ | |||||||
|         "semver": "5.4.1" |         "semver": "5.4.1" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "server-destroy": { | ||||||
|  |       "version": "1.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", | ||||||
|  |       "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=" | ||||||
|  |     }, | ||||||
|     "set-blocking": { |     "set-blocking": { | ||||||
|       "version": "2.0.0", |       "version": "2.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", |       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", | ||||||
|   | |||||||
| @@ -114,6 +114,7 @@ | |||||||
|     "read-chunk": "^2.1.0", |     "read-chunk": "^2.1.0", | ||||||
|     "readability-node": "^0.1.0", |     "readability-node": "^0.1.0", | ||||||
|     "redux": "^3.7.2", |     "redux": "^3.7.2", | ||||||
|  |     "server-destroy": "^1.0.1", | ||||||
|     "smalltalk": "^2.5.1", |     "smalltalk": "^2.5.1", | ||||||
|     "sprintf-js": "^1.1.1", |     "sprintf-js": "^1.1.1", | ||||||
|     "sqlite3": "^3.1.13", |     "sqlite3": "^3.1.13", | ||||||
|   | |||||||
| @@ -34,7 +34,6 @@ const SyncTargetDropbox = require('lib/SyncTargetDropbox.js'); | |||||||
| const EncryptionService = require('lib/services/EncryptionService'); | const EncryptionService = require('lib/services/EncryptionService'); | ||||||
| const DecryptionWorker = require('lib/services/DecryptionWorker'); | const DecryptionWorker = require('lib/services/DecryptionWorker'); | ||||||
| const BaseService = require('lib/services/BaseService'); | const BaseService = require('lib/services/BaseService'); | ||||||
| const ClipperServer = require('lib/ClipperServer'); |  | ||||||
|  |  | ||||||
| SyncTargetRegistry.addClass(SyncTargetFilesystem); | SyncTargetRegistry.addClass(SyncTargetFilesystem); | ||||||
| SyncTargetRegistry.addClass(SyncTargetOneDrive); | SyncTargetRegistry.addClass(SyncTargetOneDrive); | ||||||
| @@ -493,13 +492,6 @@ class BaseApplication { | |||||||
|  |  | ||||||
| 		// await this.testing();process.exit(); | 		// await this.testing();process.exit(); | ||||||
|  |  | ||||||
| 		const clipperLogger = new Logger(); |  | ||||||
| 		clipperLogger.addTarget('file', { path: profileDir + '/log-clipper.txt' }); |  | ||||||
| 		clipperLogger.addTarget('console'); |  | ||||||
| 		this.clipperServer_ = new ClipperServer(); |  | ||||||
| 		this.clipperServer_.setLogger(clipperLogger); |  | ||||||
| 		this.clipperServer_.start(); |  | ||||||
|  |  | ||||||
| 		return argv; | 		return argv; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,11 +12,21 @@ const { Logger } = require('lib/logger.js'); | |||||||
| const markdownUtils = require('lib/markdownUtils'); | const markdownUtils = require('lib/markdownUtils'); | ||||||
| const mimeUtils = require('lib/mime-utils.js').mime; | const mimeUtils = require('lib/mime-utils.js').mime; | ||||||
| const randomClipperPort = require('lib/randomClipperPort'); | const randomClipperPort = require('lib/randomClipperPort'); | ||||||
|  | const enableServerDestroy = require('server-destroy'); | ||||||
|  |  | ||||||
| class ClipperServer { | class ClipperServer { | ||||||
|  |  | ||||||
| 	constructor() { | 	constructor() { | ||||||
| 		this.logger_ = new Logger(); | 		this.logger_ = new Logger(); | ||||||
|  | 		this.startState_ = 'idle'; | ||||||
|  | 		this.server_ = null; | ||||||
|  | 		this.port_ = null; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static instance() { | ||||||
|  | 		if (this.instance_) return this.instance_; | ||||||
|  | 		this.instance_ = new ClipperServer(); | ||||||
|  | 		return this.instance_; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	setLogger(l) { | 	setLogger(l) { | ||||||
| @@ -27,6 +37,41 @@ class ClipperServer { | |||||||
| 		return this.logger_; | 		return this.logger_; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	setDispatch(d) { | ||||||
|  | 		this.dispatch_ = d; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dispatch(action) { | ||||||
|  | 		if (!this.dispatch_) throw new Error('dispatch not set!'); | ||||||
|  | 		this.dispatch_(action); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	setStartState(v) { | ||||||
|  | 		if (this.startState_ === v) return; | ||||||
|  | 		this.startState_ = v; | ||||||
|  | 		this.dispatch({ | ||||||
|  | 			type: 'CLIPPER_SERVER_SET', | ||||||
|  | 			startState: v, | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	setPort(v) { | ||||||
|  | 		if (this.port_ === v) return; | ||||||
|  | 		this.port_ = v; | ||||||
|  | 		this.dispatch({ | ||||||
|  | 			type: 'CLIPPER_SERVER_SET', | ||||||
|  | 			port: v, | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// startState() { | ||||||
|  | 	// 	return this.startState_; | ||||||
|  | 	// } | ||||||
|  |  | ||||||
|  | 	// port() { | ||||||
|  | 	// 	return this.port_; | ||||||
|  | 	// } | ||||||
|  |  | ||||||
| 	htmlToMdParser() { | 	htmlToMdParser() { | ||||||
| 		if (this.htmlToMdParser_) return this.htmlToMdParser_; | 		if (this.htmlToMdParser_) return this.htmlToMdParser_; | ||||||
| 		this.htmlToMdParser_ = new HtmlToMd(); | 		this.htmlToMdParser_ = new HtmlToMd(); | ||||||
| @@ -167,18 +212,22 @@ class ClipperServer { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	async start() { | 	async start() { | ||||||
| 		let port = null; | 		this.setPort(null); | ||||||
|  |  | ||||||
|  | 		this.setStartState('starting'); | ||||||
|  |  | ||||||
| 		try { | 		try { | ||||||
| 			port = await this.findAvailablePort(); | 			const p = await this.findAvailablePort(); | ||||||
|  | 			this.setPort(p); | ||||||
| 		} catch (error) { | 		} catch (error) { | ||||||
|  | 			this.setStartState('idle'); | ||||||
| 			this.logger().error(error); | 			this.logger().error(error); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const server = require('http').createServer(); | 		this.server_ = require('http').createServer(); | ||||||
|  |  | ||||||
| 		server.on('request', (request, response) => { | 		this.server_.on('request', (request, response) => { | ||||||
|  |  | ||||||
| 			const writeCorsHeaders = (code) => { | 			const writeCorsHeaders = (code) => { | ||||||
| 				response.writeHead(code, { | 				response.writeHead(code, { | ||||||
| @@ -253,13 +302,24 @@ class ClipperServer { | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		server.on('close', () => { | 		this.server_.on('close', () => { | ||||||
|  |  | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		this.logger().info('Starting Clipper server on port ' + port); | 		enableServerDestroy(this.server_); | ||||||
|  |  | ||||||
| 		server.listen(port); | 		this.logger().info('Starting Clipper server on port ' + this.port_); | ||||||
|  |  | ||||||
|  | 		this.server_.listen(this.port_); | ||||||
|  |  | ||||||
|  | 		this.setStartState('started'); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	async stop() { | ||||||
|  | 		this.server_.destroy(); | ||||||
|  | 		this.server_ = null; | ||||||
|  | 		this.setStartState('idle'); | ||||||
|  | 		this.setPort(null); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -102,6 +102,7 @@ class Setting extends BaseModel { | |||||||
| 			'style.zoom': {value: "100", type: Setting.TYPE_INT, public: true, appTypes: ['desktop'], label: () => _('Global zoom percentage'), minimum: "50", maximum: "500", step: "10"}, | 			'style.zoom': {value: "100", type: Setting.TYPE_INT, public: true, appTypes: ['desktop'], label: () => _('Global zoom percentage'), minimum: "50", maximum: "500", step: "10"}, | ||||||
| 			'style.editor.fontFamily': {value: "", type: Setting.TYPE_STRING, public: true, appTypes: ['desktop'], label: () => _('Editor font family'), description: () => _('The font name will not be checked. If incorrect or empty, it will default to a generic monospace font.')}, | 			'style.editor.fontFamily': {value: "", type: Setting.TYPE_STRING, public: true, appTypes: ['desktop'], label: () => _('Editor font family'), description: () => _('The font name will not be checked. If incorrect or empty, it will default to a generic monospace font.')}, | ||||||
| 			'autoUpdateEnabled': { value: true, type: Setting.TYPE_BOOL, public: true, appTypes: ['desktop'], label: () => _('Automatically update the application') }, | 			'autoUpdateEnabled': { value: true, type: Setting.TYPE_BOOL, public: true, appTypes: ['desktop'], label: () => _('Automatically update the application') }, | ||||||
|  | 			'clipperServer.autoStart': { value: false, type: Setting.TYPE_BOOL, public: false }, | ||||||
| 			'sync.interval': { value: 300, type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation interval'), options: () => { | 			'sync.interval': { value: 300, type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation interval'), options: () => { | ||||||
| 				return { | 				return { | ||||||
| 					0: _('Disabled'), | 					0: _('Disabled'), | ||||||
|   | |||||||
| @@ -34,9 +34,6 @@ const reservedPorts = [1024, 1027, 1028, 1029, 1058, 1059, 1080, 1085, 1098, 109 | |||||||
|  |  | ||||||
| // From https://github.com/coverslide/node-alea | // From https://github.com/coverslide/node-alea | ||||||
| const AleaModule = function () { | const AleaModule = function () { | ||||||
|  |  | ||||||
|   'use strict'; |  | ||||||
|  |  | ||||||
|   // importState to sync generator states |   // importState to sync generator states | ||||||
|   Alea.importState = function(i){ |   Alea.importState = function(i){ | ||||||
|     var random = new Alea(); |     var random = new Alea(); | ||||||
| @@ -54,8 +51,8 @@ const AleaModule = function () { | |||||||
|       var s2 = 0; |       var s2 = 0; | ||||||
|       var c = 1; |       var c = 1; | ||||||
|  |  | ||||||
|       if (args.length == 0) { |       if (args.length === 0) { | ||||||
|         args = [+new Date]; |         args = [+new Date()]; | ||||||
|       } |       } | ||||||
|       var mash = Mash(); |       var mash = Mash(); | ||||||
|       s0 = mash(' '); |       s0 = mash(' '); | ||||||
|   | |||||||
| @@ -27,6 +27,10 @@ const defaultState = { | |||||||
| 	hasDisabledSyncItems: false, | 	hasDisabledSyncItems: false, | ||||||
| 	newNote: null, | 	newNote: null, | ||||||
| 	collapsedFolderIds: [], | 	collapsedFolderIds: [], | ||||||
|  | 	clipperServer: { | ||||||
|  | 		startState: 'idle', | ||||||
|  | 		port: null, | ||||||
|  | 	}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const stateUtils = {}; | const stateUtils = {}; | ||||||
| @@ -525,7 +529,16 @@ const reducer = (state = defaultState, action) => { | |||||||
|  |  | ||||||
| 				newState = Object.assign({}, state); | 				newState = Object.assign({}, state); | ||||||
| 				newState.newNote = action.item; | 				newState.newNote = action.item; | ||||||
| 				break;				 | 				break; | ||||||
|  |  | ||||||
|  | 			case 'CLIPPER_SERVER_SET': | ||||||
|  |  | ||||||
|  | 				newState = Object.assign({}, state); | ||||||
|  | 				const clipperServer = Object.assign({}, newState.clipperServer); | ||||||
|  | 				if ('startState' in action) clipperServer.startState = action.startState; | ||||||
|  | 				if ('port' in action) clipperServer.port = action.port; | ||||||
|  | 				newState.clipperServer = clipperServer; | ||||||
|  | 				break;	 | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} catch (error) { | 	} catch (error) { | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								Tools/release-clipper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								Tools/release-clipper.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | const fs = require('fs-extra'); | ||||||
|  | const { execCommand } = require('./tool-utils.js'); | ||||||
|  |  | ||||||
|  | const clipperDir = __dirname + '/../Clipper/joplin-webclipper'; | ||||||
|  |  | ||||||
|  | async function copyDir(baseSourceDir, sourcePath, baseDestDir) { | ||||||
|  | 	await fs.mkdirp(baseDestDir + '/' + sourcePath); | ||||||
|  | 	await fs.copy(baseSourceDir + '/' + sourcePath, baseDestDir + '/' + sourcePath); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function copyToDist(distDir) { | ||||||
|  | 	await copyDir(clipperDir, 'popup/build', distDir); | ||||||
|  | 	await copyDir(clipperDir, 'content_scripts', distDir); | ||||||
|  | 	await copyDir(clipperDir, 'icons', distDir); | ||||||
|  | 	await fs.copy(clipperDir + '/background.js', distDir + '/background.js'); | ||||||
|  | 	await fs.copy(clipperDir + '/main.js', distDir + '/main.js'); | ||||||
|  | 	await fs.copy(clipperDir + '/manifest.json', distDir + '/manifest.json'); | ||||||
|  |  | ||||||
|  | 	await fs.remove(distDir + '/popup/build/manifest.json'); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function main() { | ||||||
|  | 	process.chdir(clipperDir + '/popup'); | ||||||
|  |  | ||||||
|  | 	console.info(await execCommand('npm run build')); | ||||||
|  |  | ||||||
|  | 	const dists = [ | ||||||
|  | 		{ | ||||||
|  | 			dir: clipperDir + '/dist/chrometest', | ||||||
|  | 			name: 'chrome', | ||||||
|  | 		} | ||||||
|  | 	]; | ||||||
|  |  | ||||||
|  | 	for (let i = 0; i < dists.length; i++) { | ||||||
|  | 		const dist = dists[i]; | ||||||
|  | 		await copyToDist(dist.dir); | ||||||
|  | 		process.chdir(dist.dir); | ||||||
|  | 		console.info(await execCommand('7z a -tzip ' + dist.name + '.zip *')); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | main().catch((error) => { | ||||||
|  | 	console.error('Fatal error'); | ||||||
|  | 	console.error(error); | ||||||
|  | 	process.exit(1); | ||||||
|  | }); | ||||||
		Reference in New Issue
	
	Block a user