From df37ed8583a2565f2752c4314ff9e35b6a34fb72 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Wed, 17 Apr 2024 12:25:58 +0200 Subject: [PATCH 01/17] Initializing variables --- backend/helpers.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/helpers.js b/backend/helpers.js index 427d360..0976293 100644 --- a/backend/helpers.js +++ b/backend/helpers.js @@ -4,12 +4,12 @@ const path = require('path') async function openFolderDialog(win) { // https://stackoverflow.com/questions/46027287/electron-open-folder-dialog - let dir = await dialog.showOpenDialog(win, { properties: [ 'openDirectory' ] }) + const dir = await dialog.showOpenDialog(win, { properties: [ 'openDirectory' ] }) return dir.filePaths[0] || null } function listFolder(folder) { - files = fs.readdirSync(path.resolve(folder)) + let files = fs.readdirSync(path.resolve(folder)) // Filter out directories files = files.filter(f => { let filePath = path.resolve(folder, f) @@ -38,7 +38,7 @@ function ilistFolder(folder) { function getAllFiles(dirPath, arrayOfFiles) { // https://coderrocketfuel.com/article/recursively-list-all-the-files-in-a-directory-using-node-js - files = ilistFolder(dirPath) + let files = ilistFolder(dirPath) arrayOfFiles = arrayOfFiles || [] files.forEach(function(file) { const p = path.join(dirPath, file.path) From ba3241d3ca0c86f34758985ee629307c0c6663d1 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Wed, 17 Apr 2024 12:26:37 +0200 Subject: [PATCH 02/17] Electron will wait for UI to confirm close --- backend/ipc.js | 13 ++++++++++++- index.js | 10 ++++++++-- preload.js | 5 ++++- ui/arduino/store.js | 9 +++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/backend/ipc.js b/backend/ipc.js index c97daba..b1133b4 100644 --- a/backend/ipc.js +++ b/backend/ipc.js @@ -6,7 +6,7 @@ const { getAllFiles } = require('./helpers.js') -module.exports = function registerIPCHandlers(win, ipcMain) { +module.exports = function registerIPCHandlers(win, ipcMain, app) { ipcMain.handle('open-folder', async (event) => { console.log('ipcMain', 'open-folder') const folder = await openFolderDialog(win) @@ -107,4 +107,15 @@ module.exports = function registerIPCHandlers(win, ipcMain) { win.setMinimumSize(minWidth, minHeight) }) + + ipcMain.handle('confirm-close', () => { + console.log('ipcMain', 'confirm-close') + app.exit() + }) + + win.on('close', (event) => { + console.log('BrowserWindow', 'close') + event.preventDefault() + win.webContents.send('check-before-close') + }) } diff --git a/index.js b/index.js index 2992967..3f01633 100644 --- a/index.js +++ b/index.js @@ -23,11 +23,17 @@ function createWindow () { // and load the index.html of the app. win.loadFile('ui/arduino/index.html') - registerIPCHandlers(win, ipcMain) + registerIPCHandlers(win, ipcMain, app) registerMenu(win) + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) createWindow() + }) + // app.on('window-all-closed', () => { + // if (process.platform !== 'darwin') app.quit() + // }) } // TODO: Loading splash screen - app.whenReady().then(createWindow) diff --git a/preload.js b/preload.js index d7b24e8..cce145f 100644 --- a/preload.js +++ b/preload.js @@ -151,9 +151,12 @@ const Disk = { const Window = { setWindowSize: (minWidth, minHeight) => { ipcRenderer.invoke('set-window-size', minWidth, minHeight) - } + }, + beforeClose: (callback) => ipcRenderer.on('check-before-close', callback), + confirmClose: () => ipcRenderer.invoke('confirm-close') } + contextBridge.exposeInMainWorld('BridgeSerial', Serial) contextBridge.exposeInMainWorld('BridgeDisk', Disk) contextBridge.exposeInMainWorld('BridgeWindow', Window) diff --git a/ui/arduino/store.js b/ui/arduino/store.js index 80656a5..6d965e7 100644 --- a/ui/arduino/store.js +++ b/ui/arduino/store.js @@ -1303,6 +1303,15 @@ async function store(state, emitter) { emitter.emit('render') }) + win.beforeClose(async () => { + const hasChanges = !!state.openFiles.find(f => f.parentFolder && f.hasChanges) + if (hasChanges) { + const response = await confirm('You may have unsaved changes. Are you sure you want to proceed?', 'Yes', 'Cancel') + if (!response) return false + } + await win.confirmClose() + }) + function createFile(args) { const { source, From 8515dd52bc9c28d2a1bb5a78c41a1d39be81cd5a Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Thu, 18 Apr 2024 12:32:35 +0200 Subject: [PATCH 03/17] Remember scroll position between tabs --- ui/arduino/views/components/elements/editor.js | 18 +++++++++++++++++- ui/arduino/views/components/elements/tab.js | 8 ++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/ui/arduino/views/components/elements/editor.js b/ui/arduino/views/components/elements/editor.js index 81d6fcb..9097936 100644 --- a/ui/arduino/views/components/elements/editor.js +++ b/ui/arduino/views/components/elements/editor.js @@ -3,15 +3,31 @@ class CodeMirrorEditor extends Component { super() this.editor = null this.content = '# empty file' + this.scrollTop = 0 } load(el) { const onCodeChange = (update) => { - // console.log('code change', this.content) this.content = update.state.doc.toString() this.onChange() } this.editor = createEditor(this.content, el, onCodeChange) + this.editor.scrollDOM.addEventListener('scroll', this.updateScrollPosition.bind(this)) + setTimeout(() => { + this.editor.scrollDOM.scrollTo({ + top: this.scrollTop, + left: 0 + }) + }, 1) + } + + updateScrollPosition(e) { + console.log(e.target.scrollTop) + this.scrollTop = e.target.scrollTop + } + + unload() { + this.editor.scrollDOM.removeEventListener('scroll', this.updateScrollPosition) } createElement(content) { diff --git a/ui/arduino/views/components/elements/tab.js b/ui/arduino/views/components/elements/tab.js index f0070f3..6036d6b 100644 --- a/ui/arduino/views/components/elements/tab.js +++ b/ui/arduino/views/components/elements/tab.js @@ -57,7 +57,7 @@ function Tab(args) { } function selectTab(e) { - if(e.target.tagName === 'BUTTON' || e.target.tagName === 'IMG') return + if(e.target.classList.contains('close-tab')) return onSelectTab(e) } @@ -71,9 +71,9 @@ function Tab(args) {
${hasChanges ? '*' : ''} ${text}
-
-
From fef591641750221b9578710b2fdc16e201040551 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Thu, 18 Apr 2024 15:09:08 +0200 Subject: [PATCH 04/17] Increase timeout --- .../views/components/elements/editor.js | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/ui/arduino/views/components/elements/editor.js b/ui/arduino/views/components/elements/editor.js index 9097936..4158d4a 100644 --- a/ui/arduino/views/components/elements/editor.js +++ b/ui/arduino/views/components/elements/editor.js @@ -6,37 +6,39 @@ class CodeMirrorEditor extends Component { this.scrollTop = 0 } + createElement(content) { + if (content) this.content = content + return html`
` + } + + load(el) { const onCodeChange = (update) => { this.content = update.state.doc.toString() this.onChange() } this.editor = createEditor(this.content, el, onCodeChange) - this.editor.scrollDOM.addEventListener('scroll', this.updateScrollPosition.bind(this)) + setTimeout(() => { + this.editor.scrollDOM.addEventListener('scroll', this.updateScrollPosition.bind(this)) this.editor.scrollDOM.scrollTo({ top: this.scrollTop, left: 0 }) - }, 1) + }, 10) } - updateScrollPosition(e) { - console.log(e.target.scrollTop) - this.scrollTop = e.target.scrollTop + update() { + return false } unload() { this.editor.scrollDOM.removeEventListener('scroll', this.updateScrollPosition) } - createElement(content) { - if (content) this.content = content - return html`
` - } - - update() { - return false + updateScrollPosition(e) { + console.log(e.target.scrollTop) + this.scrollTop = e.target.scrollTop } onChange() { From b868efee9ef230e73d872ecfe069adfdc0262d2d Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Thu, 18 Apr 2024 16:13:32 +0200 Subject: [PATCH 05/17] Remove console.log --- ui/arduino/views/components/elements/editor.js | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/arduino/views/components/elements/editor.js b/ui/arduino/views/components/elements/editor.js index 4158d4a..091c6fa 100644 --- a/ui/arduino/views/components/elements/editor.js +++ b/ui/arduino/views/components/elements/editor.js @@ -37,7 +37,6 @@ class CodeMirrorEditor extends Component { } updateScrollPosition(e) { - console.log(e.target.scrollTop) this.scrollTop = e.target.scrollTop } From edfccf80ea75d30596dbe6be1c3c031404235d48 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Fri, 19 Apr 2024 07:44:30 +0200 Subject: [PATCH 06/17] First Apple Silicon build support. Signed-off-by: ubi de feo --- .github/workflows/build.yml | 3 ++- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 137a1ec..252f774 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,8 @@ jobs: config: - os: windows-2019 - os: ubuntu-latest - - os: macos-latest + - os: macos-13 + - os: macos-14 runs-on: ${{ matrix.config.os }} timeout-minutes: 90 diff --git a/package-lock.json b/package-lock.json index 61b8548..d2c4e01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "arduino-lab-micropython-ide", - "version": "0.9.0", + "version": "0.9.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "arduino-lab-micropython-ide", - "version": "0.9.0", + "version": "0.9.1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index ad5c2cd..74ab24b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "post-set-shell": "npm config set script-shell bash", "rebuild": "electron-rebuild", "dev": "electron --inspect ./", - "build": "npm run post-set-shell && electron-builder $(if [ $(uname -m) = arm64 ]; then echo --mac --x64; fi)", + "build": "npm run post-set-shell && electron-builder", "postinstall": "npm run post-set-shell && npm run rebuild" }, "devDependencies": { From 87bf0d10dd4c59abec0695759dcc8fad510efeb7 Mon Sep 17 00:00:00 2001 From: ubi de feo Date: Fri, 19 Apr 2024 08:03:35 +0200 Subject: [PATCH 07/17] Workflow: added arm64 to artifacts matrix. Signed-off-by: ubi de feo --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 252f774..9f35452 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,6 +100,8 @@ jobs: name: Arduino-Lab-for-MicroPython_Linux_X86-64 - path: "*-mac_x64.zip" name: Arduino-Lab-for-MicroPython_macOS_X86-64 + - path: "*-mac_arm64.zip" + name: Arduino-Lab-for-MicroPython_macOS_arm-64 # - path: "*Windows_64bit.exe" # name: Windows_X86-64_interactive_installer # - path: "*Windows_64bit.msi" From 83d5d595d1e7815b34f110820f7504bdcae9c925 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Mon, 22 Apr 2024 14:07:36 +0200 Subject: [PATCH 08/17] Make a component for overlays --- ui/arduino/index.html | 1 + ui/arduino/main.js | 31 +++++++++++++------------- ui/arduino/views/components/overlay.js | 16 +++++++++++++ 3 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 ui/arduino/views/components/overlay.js diff --git a/ui/arduino/index.html b/ui/arduino/index.html index 25f1967..8478cc7 100644 --- a/ui/arduino/index.html +++ b/ui/arduino/index.html @@ -30,6 +30,7 @@ + diff --git a/ui/arduino/main.js b/ui/arduino/main.js index f7d1ef7..c5e68e5 100644 --- a/ui/arduino/main.js +++ b/ui/arduino/main.js @@ -19,27 +19,26 @@ function App(state, emit) { ` } - let overlay = html`
` - - if (state.diskFiles == null) { - emit('load-disk-files') - overlay = html`

Loading files...

` + if (state.view == 'file-manager') { + return html` +
+ ${FileManagerView(state, emit)} + ${Overlay(state, emit)} +
+ ` + } else { + return html` +
+ ${EditorView(state, emit)} + ${Overlay(state, emit)} +
+ ` } - - if (state.isRemoving) overlay = html`

Removing...

` - if (state.isConnecting) overlay = html`

Connecting...

` - if (state.isLoadingFiles) overlay = html`

Loading files...

` - if (state.isSaving) overlay = html`

Saving file... ${state.savingProgress}

` - if (state.isTransferring) overlay = html`

Transferring file... ${state.transferringProgress}

` - - const view = state.view == 'editor' ? EditorView(state, emit) : FileManagerView(state, emit) return html`
- ${view} - ${overlay} + ${Overlay(state, emit)}
` - } window.addEventListener('load', () => { diff --git a/ui/arduino/views/components/overlay.js b/ui/arduino/views/components/overlay.js new file mode 100644 index 0000000..1b9389c --- /dev/null +++ b/ui/arduino/views/components/overlay.js @@ -0,0 +1,16 @@ +function Overlay(state, emit) { + let overlay = html`
` + + if (state.diskFiles == null) { + emit('load-disk-files') + overlay = html`

Loading files...

` + } + + if (state.isRemoving) overlay = html`

Removing...

` + if (state.isConnecting) overlay = html`

Connecting...

` + if (state.isLoadingFiles) overlay = html`

Loading files...

` + if (state.isSaving) overlay = html`

Saving file... ${state.savingProgress}

` + if (state.isTransferring) overlay = html`

Transferring file... ${state.transferringProgress}

` + + return overlay +} From 51430789fb87265627772181c824d1ee70fe9639 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Mon, 22 Apr 2024 14:08:13 +0200 Subject: [PATCH 09/17] No need to use `await` here --- preload.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/preload.js b/preload.js index cce145f..05abf0c 100644 --- a/preload.js +++ b/preload.js @@ -13,10 +13,10 @@ const Serial = { return ports.filter(p => p.vendorId && p.productId) }, connect: async (path) => { - return await board.open(path) + return board.open(path) }, disconnect: async () => { - return await board.close() + return board.close() }, run: async (code) => { return board.run(code) From ec733cabcaf45640fff0c844995f354b0c35a7b6 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Mon, 22 Apr 2024 14:08:42 +0200 Subject: [PATCH 10/17] Check if there is a `diskNavigationRoot` before refreshing files --- ui/arduino/main.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/arduino/main.js b/ui/arduino/main.js index c5e68e5..bf693df 100644 --- a/ui/arduino/main.js +++ b/ui/arduino/main.js @@ -48,7 +48,9 @@ window.addEventListener('load', () => { app.mount('#app') app.emitter.on('DOMContentLoaded', () => { - app.emitter.emit('refresh-files') + if (app.state.diskNavigationRoot) { + app.emitter.emit('refresh-files') + } }) }) From c13304ab21eff0beb2fe0940778c56718c55f2d6 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Tue, 23 Apr 2024 09:26:57 +0200 Subject: [PATCH 11/17] Enable devtools on production --- backend/menu.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/backend/menu.js b/backend/menu.js index 3ee40a6..6b62cdf 100644 --- a/backend/menu.js +++ b/backend/menu.js @@ -4,7 +4,6 @@ const openAboutWindow = require('about-window').default module.exports = function registerMenu(win) { const isMac = process.platform === 'darwin' - const isDev = !app.isPackaged const template = [ ...(isMac ? [{ label: app.name, @@ -56,17 +55,13 @@ module.exports = function registerMenu(win) { label: 'View', submenu: [ { role: 'reload' }, + { role: 'toggleDevTools' }, { type: 'separator' }, { role: 'resetZoom' }, { role: 'zoomIn' }, { role: 'zoomOut' }, { type: 'separator' }, { role: 'togglefullscreen' }, - ...(isDev ? [ - { type: 'separator' }, - { role: 'toggleDevTools' }, - ]:[ - ]) ] }, { From 3c3eecc8478747e3cb632021ed80d3415d9adb0d Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Tue, 23 Apr 2024 10:41:48 +0200 Subject: [PATCH 12/17] Splash screen --- index.js | 30 +++++++++++++++++++++++------- ui/arduino/splash.html | 21 +++++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 ui/arduino/splash.html diff --git a/index.js b/index.js index 3f01633..e2130c6 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,8 @@ const registerIPCHandlers = require('./backend/ipc.js') const registerMenu = require('./backend/menu.js') let win = null // main window +let splash = null +let splashTimeout = null // START APP function createWindow () { @@ -17,11 +19,30 @@ function createWindow () { nodeIntegration: false, webSecurity: true, enableRemoteModule: false, - preload: path.join(__dirname, "preload.js") + preload: path.join(__dirname, "preload.js"), + show: false } }) // and load the index.html of the app. win.loadFile('ui/arduino/index.html') + // If the app takes a while to open, show splash screen + splashTimeout = setTimeout(() => { + // Create the splash screen + splash = new BrowserWindow({ + width: 560, + height: 180, + transparent: true, + frame: false, + alwaysOnTop: true + }); + splash.loadFile('ui/arduino/splash.html') + }, 250) + + win.once('ready-to-show', () => { + clearTimeout(splashTimeout) + if (splash) splash.destroy() + win.show() + }) registerIPCHandlers(win, ipcMain, app) registerMenu(win) @@ -29,11 +50,6 @@ function createWindow () { app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) - // app.on('window-all-closed', () => { - // if (process.platform !== 'darwin') app.quit() - // }) } - -// TODO: Loading splash screen -app.whenReady().then(createWindow) +app.on('ready', createWindow) diff --git a/ui/arduino/splash.html b/ui/arduino/splash.html new file mode 100644 index 0000000..6d7e2e1 --- /dev/null +++ b/ui/arduino/splash.html @@ -0,0 +1,21 @@ + + + + + Arduino Lab for MicroPython + + + + Arduino Lab For MicroPython Logo + + From 4aadc2935fd9500aae826e38652da32021d420fa Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Tue, 23 Apr 2024 11:40:43 +0200 Subject: [PATCH 13/17] Encoding image as base64 to load faster --- ui/arduino/splash.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/arduino/splash.html b/ui/arduino/splash.html index 6d7e2e1..15ae0b4 100644 --- a/ui/arduino/splash.html +++ b/ui/arduino/splash.html @@ -16,6 +16,6 @@ - Arduino Lab For MicroPython Logo + Arduino Lab For MicroPython Logo From 2b36cfabf2552dcb7dc416943740e0c06bfb6703 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Tue, 23 Apr 2024 11:44:30 +0200 Subject: [PATCH 14/17] Always show the splash screen for a brief time --- index.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/index.js b/index.js index e2130c6..b38f989 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,7 @@ const registerMenu = require('./backend/menu.js') let win = null // main window let splash = null -let splashTimeout = null +let splashTimestamp = null // START APP function createWindow () { @@ -25,22 +25,27 @@ function createWindow () { }) // and load the index.html of the app. win.loadFile('ui/arduino/index.html') + // If the app takes a while to open, show splash screen - splashTimeout = setTimeout(() => { - // Create the splash screen - splash = new BrowserWindow({ - width: 560, - height: 180, - transparent: true, - frame: false, - alwaysOnTop: true - }); - splash.loadFile('ui/arduino/splash.html') - }, 250) + // Create the splash screen + splash = new BrowserWindow({ + width: 450, + height: 140, + transparent: true, + frame: false, + alwaysOnTop: true + }); + splash.loadFile('ui/arduino/splash.html') + splashTimestamp = Date.now() win.once('ready-to-show', () => { - clearTimeout(splashTimeout) - if (splash) splash.destroy() + if (Date.now()-splashTimestamp > 1000) { + splash.destroy() + } else { + setTimeout(() => { + splash.destroy() + }, 500) + } win.show() }) From 36b169a103cc457a6012586f030fabf8a05c8688 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Tue, 23 Apr 2024 17:30:35 +0200 Subject: [PATCH 15/17] Switch to tab if file is already open --- ui/arduino/store.js | 139 +++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 72 deletions(-) diff --git a/ui/arduino/store.js b/ui/arduino/store.js index 6d965e7..93ed063 100644 --- a/ui/arduino/store.js +++ b/ui/arduino/store.js @@ -1021,17 +1021,19 @@ async function store(state, emitter) { emitter.on('toggle-file-selection', (file, source, event) => { log('toggle-file-selection', file, source, event) + let parentFolder = source == 'board' ? state.boardNavigationPath : state.diskNavigationPath // Single file selection unless holding keyboard key if (event && !event.ctrlKey && !event.metaKey) { state.selectedFiles = [{ fileName: file.fileName, type: file.type, source: source, - parentFolder: file.parentFolder + parentFolder: parentFolder }] emitter.emit('render') return } + const isSelected = state.selectedFiles.find((f) => { return f.fileName === file.fileName && f.source === source }) @@ -1044,80 +1046,90 @@ async function store(state, emitter) { fileName: file.fileName, type: file.type, source: source, - parentFolder: file.parentFolder + parentFolder: parentFolder }) } emitter.emit('render') }) emitter.on('open-selected-files', async () => { log('open-selected-files') - let files = [] + let filesToOpen = [] + let filesAlreadyOpen = [] for (let i in state.selectedFiles) { let selectedFile = state.selectedFiles[i] - let openFile = null if (selectedFile.type == 'folder') { // Don't open folders continue } - if (selectedFile.source == 'board') { - const fileContent = await serial.loadFile( - serial.getFullPath( - '/', - state.boardNavigationPath, - selectedFile.fileName + // ALl good until here + + const alreadyOpen = state.openFiles.find((f) => { + return f.fileName == selectedFile.fileName + && f.source == selectedFile.source + && f.parentFolder == selectedFile.parentFolder + }) + console.log('already open', alreadyOpen) + + if (!alreadyOpen) { + // This file is not open yet, + // load content and append it to the list of files to open + let file = null + if (selectedFile.source == 'board') { + const fileContent = await serial.loadFile( + serial.getFullPath( + state.boardNavigationRoot, + state.boardNavigationPath, + selectedFile.fileName + ) ) - ) - openFile = createFile({ - parentFolder: state.boardNavigationPath, - fileName: selectedFile.fileName, - source: selectedFile.source, - content: fileContent - }) - openFile.editor.onChange = function() { - openFile.hasChanges = true - emitter.emit('render') - } - } else if (selectedFile.source == 'disk') { - const fileContent = await disk.loadFile( - disk.getFullPath( - state.diskNavigationRoot, - state.diskNavigationPath, - selectedFile.fileName + file = createFile({ + parentFolder: state.boardNavigationPath, + fileName: selectedFile.fileName, + source: selectedFile.source, + content: fileContent + }) + file.editor.onChange = function() { + file.hasChanges = true + emitter.emit('render') + } + } else if (selectedFile.source == 'disk') { + const fileContent = await disk.loadFile( + disk.getFullPath( + state.diskNavigationRoot, + state.diskNavigationPath, + selectedFile.fileName + ) ) - ) - openFile = createFile({ - parentFolder: state.diskNavigationPath, - fileName: selectedFile.fileName, - source: selectedFile.source, - content: fileContent - }) - openFile.editor.onChange = function() { - openFile.hasChanges = true - emitter.emit('render') + file = createFile({ + parentFolder: state.diskNavigationPath, + fileName: selectedFile.fileName, + source: selectedFile.source, + content: fileContent + }) + file.editor.onChange = function() { + file.hasChanges = true + emitter.emit('render') + } } + filesToOpen.push(file) + } else { + // This file is already open, + // append it to the list of files that are already open + filesAlreadyOpen.push(alreadyOpen) } - files.push(openFile) } - files = files.filter((f) => { // find files to open - let isAlready = false - state.openFiles.forEach((g) => { // check if file is already open - if ( - g.fileName == f.fileName - && g.source == f.source - && g.parentFolder == f.parentFolder - ) { - isAlready = true - } - }) - return !isAlready - }) - - if (files.length > 0) { - state.openFiles = state.openFiles.concat(files) - state.editingFile = files[0].id + // If opening an already open file, switch to its tab + if (filesAlreadyOpen.length > 0) { + state.editingFile = filesAlreadyOpen[0].id + } + // If there are new files to open, they take priority + if (filesToOpen.length > 0) { + state.editingFile = filesToOpen[0].id } + state.openFiles = state.openFiles.concat(filesToOpen) + state.view = 'editor' emitter.emit('render') }) @@ -1476,23 +1488,6 @@ function canEdit({ selectedFiles }) { return files.length != 0 } -function toggleFileSelection({ fileName, source, selectedFiles }) { - let result = [] - let file = selectedFiles.find((f) => { - return f.fileName === fileName && f.source === source - }) - if (file) { - // filter file out - result = selectedFiles.filter((f) => { - return f.fileName !== fileName && f.source !== source - }) - } else { - // push file - selectedFiles.push({ fileName, source }) - } - return result -} - async function removeBoardFolder(fullPath) { // TODO: Replace with getting the file tree from the board and deleting one by one let output = await serial.execFile('./ui/arduino/helpers.py') From 8b085dc332e0ccdee60e18f92906100034a7a96f Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Thu, 25 Apr 2024 10:46:30 +0200 Subject: [PATCH 16/17] Include helper as extra resource and load its path correctly --- backend/ipc.js | 9 +++++++++ package.json | 1 + preload.js | 6 +++++- ui/arduino/store.js | 21 +++++++++++++++++++-- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/backend/ipc.js b/backend/ipc.js index b1133b4..d4ddc74 100644 --- a/backend/ipc.js +++ b/backend/ipc.js @@ -113,6 +113,15 @@ module.exports = function registerIPCHandlers(win, ipcMain, app) { app.exit() }) + ipcMain.handle('is-packaged', () => { + return app.isPackaged + }) + + ipcMain.handle('get-app-path', () => { + console.log('ipcMain', 'get-app-path') + return app.getAppPath() + }) + win.on('close', (event) => { console.log('BrowserWindow', 'close') event.preventDefault() diff --git a/package.json b/package.json index 74ab24b..d87247b 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "build": { "appId": "cc.arduino.micropython-lab", "artifactName": "${productName}-${os}_${arch}.${ext}", + "extraResources": "./ui/arduino/helpers.py", "mac": { "target": "zip", "icon": "build_resources/icon.icns" diff --git a/preload.js b/preload.js index 05abf0c..3388904 100644 --- a/preload.js +++ b/preload.js @@ -145,6 +145,9 @@ const Disk = { }, fileExists: async (filePath) => { return ipcRenderer.invoke('file-exists', filePath) + }, + getAppPath: () => { + return ipcRenderer.invoke('get-app-path') } } @@ -153,7 +156,8 @@ const Window = { ipcRenderer.invoke('set-window-size', minWidth, minHeight) }, beforeClose: (callback) => ipcRenderer.on('check-before-close', callback), - confirmClose: () => ipcRenderer.invoke('confirm-close') + confirmClose: () => ipcRenderer.invoke('confirm-close'), + isPackaged: () => ipcRenderer.invoke('is-packaged') } diff --git a/ui/arduino/store.js b/ui/arduino/store.js index 93ed063..f008c4b 100644 --- a/ui/arduino/store.js +++ b/ui/arduino/store.js @@ -1490,7 +1490,7 @@ function canEdit({ selectedFiles }) { async function removeBoardFolder(fullPath) { // TODO: Replace with getting the file tree from the board and deleting one by one - let output = await serial.execFile('./ui/arduino/helpers.py') + let output = await serial.execFile(await getHelperFullPath()) await serial.run(`delete_folder('${fullPath}')`) } @@ -1522,7 +1522,7 @@ async function uploadFolder(srcPath, destPath, dataConsumer) { async function downloadFolder(srcPath, destPath, dataConsumer) { dataConsumer = dataConsumer || function() {} await disk.createFolder(destPath) - let output = await serial.execFile('./ui/arduino/helpers.py') + let output = await serial.execFile(await getHelperFullPath()) output = await serial.run(`ilist_all('${srcPath}')`) let files = [] try { @@ -1550,3 +1550,20 @@ async function downloadFolder(srcPath, destPath, dataConsumer) { } } } + +async function getHelperFullPath() { + const appPath = await disk.getAppPath() + if (await win.isPackaged()) { + return disk.getFullPath( + appPath, + '..', + 'ui/arduino/helpers.py' + ) + } else { + return disk.getFullPath( + appPath, + 'ui/arduino/helpers.py', + '' + ) + } +} From caef18f8334390bac97269ec6fb83e6491ef09a6 Mon Sep 17 00:00:00 2001 From: Murilo Polese Date: Mon, 29 Apr 2024 08:39:00 +0200 Subject: [PATCH 17/17] Bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2c4e01..883d73e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "arduino-lab-micropython-ide", - "version": "0.9.1", + "version": "0.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "arduino-lab-micropython-ide", - "version": "0.9.1", + "version": "0.10.0", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index d87247b..2d3f773 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "arduino-lab-micropython-ide", "productName": "Arduino Lab for MicroPython", - "version": "0.9.1", + "version": "0.10.0", "description": "Arduino Lab for MicroPython is a project sponsored by Arduino, based on original work by Murilo Polese.\nThis is an experimental pre-release software, please direct any questions exclusively to Github issues.", "main": "index.js", "scripts": { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy