diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f7c6d53..318b18a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -24,9 +24,11 @@ jobs:
matrix:
config:
- os: [self-hosted, windows-sign-pc]
+ id: windows
- os: ubuntu-latest
- - os: macos-13
- - os: macos-14
+ id: linux
+ - os: macos-latest
+ id: macos-universal
runs-on: ${{ matrix.config.os }}
timeout-minutes: 90
@@ -92,9 +94,9 @@ jobs:
npm run build
- name: Upload [GitHub Actions]
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: ${{ env.JOB_TRANSFER_ARTIFACT }}
+ name: ${{ env.JOB_TRANSFER_ARTIFACT }}-${{ matrix.config.id }}
path: dist
artifacts:
@@ -108,26 +110,29 @@ jobs:
artifact:
- path: "*-linux_x64.zip"
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
+ id: linux
+ - path: "*-mac_universal.zip"
+ name: Arduino-Lab-for-MicroPython_macOS_Universal
+ id: macos-universal
# - path: "*Windows_64bit.exe"
# name: Windows_X86-64_interactive_installer
+ # id: windows
# - path: "*Windows_64bit.msi"
# name: Windows_X86-64_MSI
+ # id: windows
- path: "*-win_x64.zip"
name: Arduino-Lab-for-MicroPython_Windows_X86-64
+ id: windows
steps:
- name: Download job transfer artifact
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
- name: ${{ env.JOB_TRANSFER_ARTIFACT }}
+ name: ${{ env.JOB_TRANSFER_ARTIFACT }}-${{ matrix.artifact.id }}
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
- name: Upload tester build artifact
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact.name }}
path: ${{ env.JOB_TRANSFER_ARTIFACT }}/${{ matrix.artifact.path }}
@@ -137,23 +142,25 @@ jobs:
if: github.repository == 'arduino/lab-micropython-editor' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- - name: Download [GitHub Actions]
- uses: actions/download-artifact@v3
+ - name: Download all artifacts
+ uses: actions/download-artifact@v4
with:
- name: ${{ env.JOB_TRANSFER_ARTIFACT }}
- path: ${{ env.JOB_TRANSFER_ARTIFACT }}
+ path: artifacts
+
+ - name: List artifacts
+ run: ls -R artifacts
- name: Get Tag
id: tag_name
run: |
- echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/}
+ echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Publish Release [GitHub]
uses: svenstaro/upload-release-action@2.2.0
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
release_name: ${{ steps.tag_name.outputs.TAG_NAME }}
- file: ${{ env.JOB_TRANSFER_ARTIFACT }}/*
+ file: artifacts/**/*
tag: ${{ github.ref }}
file_glob: true
@@ -167,7 +174,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- - name: Remove unneeded job transfer artifact
+ - name: Remove unneeded job transfer artifacts
uses: geekyeggo/delete-artifact@v2
with:
- name: ${{ env.JOB_TRANSFER_ARTIFACT }}
+ name: |
+ ${{ env.JOB_TRANSFER_ARTIFACT }}-windows
+ ${{ env.JOB_TRANSFER_ARTIFACT }}-linux
+ ${{ env.JOB_TRANSFER_ARTIFACT }}-macos-x64
+ ${{ env.JOB_TRANSFER_ARTIFACT }}-macos-arm64
\ No newline at end of file
diff --git a/README.md b/README.md
index 3241c76..5a08600 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,41 @@
# Arduino Lab for MicroPython
-
-
- ${state.availablePorts.map(
- (port) => html`
-
emit('select-port', port)}>
- ${port.path}
-
- `
- )}
-
emit('update-ports')}>Refresh
-
+ const connectionDialog = html`
+
+
+
+
Connect to...
+ ${state.availablePorts.map(
+ (port) => html`
+
emit('select-port', port)}>
+ ${port.path}
+
+ `
+ )}
+
emit('update-ports')}>Refresh
+
+
+
`
+ if (state.isConnectionDialogOpen) {
+ return connectionDialog
+ }
+
}
diff --git a/ui/arduino/views/components/elements/button.js b/ui/arduino/views/components/elements/button.js
index 3d888dd..4ed37b9 100644
--- a/ui/arduino/views/components/elements/button.js
+++ b/ui/arduino/views/components/elements/button.js
@@ -1,25 +1,38 @@
function Button(args) {
const {
+ first = false,
size = '',
+ square = false,
icon = 'connect.svg',
- onClick = (e) => false,
+ onClick = (e) => {},
disabled = false,
active = false,
tooltip,
+ label,
background
} = args
+
+
let tooltipEl = html``
if (tooltip) {
tooltipEl = html`
${tooltip}
`
}
+ tooltipEl = html``
let activeClass = active ? 'active' : ''
+ let labelSelectedClass = active ? 'selected' : ''
let backgroundClass = background ? 'inverted' : ''
+ let buttonFirstClass = first ? 'first' : ''
+ let squareClass = square ? 'square' : ''
+ let labelActiveClass = disabled ? 'inactive' : 'active'
+ let labelItem = size === 'small' ? '' : html`
${label}
`
+
return html`
-
- `
+
+ `
}
diff --git a/ui/arduino/views/components/file-actions.js b/ui/arduino/views/components/file-actions.js
index f48e0ad..75ffd54 100644
--- a/ui/arduino/views/components/file-actions.js
+++ b/ui/arduino/views/components/file-actions.js
@@ -15,6 +15,7 @@ function FileActions(state, emit) {
icon: 'arrow-left-white.svg',
size: 'small',
background: 'inverted',
+ active: true,
disabled: !canUpload({ isConnected, selectedFiles }),
onClick: () => emit('upload-files')
})}
@@ -22,6 +23,7 @@ function FileActions(state, emit) {
icon: 'arrow-right-white.svg',
size: 'small',
background: 'inverted',
+ active: true,
disabled: !canDownload({ isConnected, selectedFiles }),
onClick: () => emit('download-files')
})}
diff --git a/ui/arduino/views/components/new-file-dialog.js b/ui/arduino/views/components/new-file-dialog.js
new file mode 100644
index 0000000..8e00d9e
--- /dev/null
+++ b/ui/arduino/views/components/new-file-dialog.js
@@ -0,0 +1,76 @@
+function NewFileDialog(state, emit) {
+ const stateClass = state.isNewFileDialogOpen ? 'open' : 'closed'
+ function clickDismiss(e) {
+ if (e.target.id == 'dialog-new-file') {
+ emit('close-new-file-dialog')
+ }
+ }
+
+ function triggerTabCreation(device) {
+ return () => {
+ const input = document.querySelector('#file-name')
+ const fileName = input.value.trim() || input.placeholder
+ emit('create-new-tab', device, fileName)
+ }
+ }
+
+ let boardOption = ''
+ let inputFocus = ''
+ if (state.isConnected) {
+ boardOption = html`
+
Board
+ `
+ }
+
+ const newFileDialogObserver = new MutationObserver((mutations, obs) => {
+ const input = document.querySelector('#dialog-new-file input')
+ if (input) {
+ input.focus()
+ obs.disconnect()
+ }
+ })
+
+ newFileDialogObserver.observe(document.body, {
+ childList: true,
+ subtree: true
+ })
+
+
+
+ let inputFieldValue = ``
+ let inputFieldPlaceholder = ``
+
+ inputFieldPlaceholder = generateFileName()
+
+ const inputAttrs = {
+ type: 'text',
+ id: 'file-name',
+ value: inputFieldValue,
+ placeholder: inputFieldPlaceholder
+ }
+
+ const randomFileName = generateFileName()
+ const placeholderAttr = state.newFileName === null ? `placeholder="${randomFileName}"` : ''
+ const newFileDialog = html`
+
+`
+
+ if (state.isNewFileDialogOpen) {
+ const el = newFileDialog.querySelector('#dialog-new-file .dialog-content > input')
+ if (el) {
+ el.focus()
+ }
+ return newFileDialog
+ }
+
+
+}
diff --git a/ui/arduino/views/components/repl-panel.js b/ui/arduino/views/components/repl-panel.js
index 3974d50..eca67d9 100644
--- a/ui/arduino/views/components/repl-panel.js
+++ b/ui/arduino/views/components/repl-panel.js
@@ -7,12 +7,22 @@ function ReplPanel(state, emit) {
}
}
const panelOpenClass = state.isPanelOpen ? 'open' : 'closed'
+ // const pointerEventsClass = state.isNewFileDialogOpen || state.isDialogOpen ? 'open' : 'closed'
const termOperationsVisibility = state.panelHeight > PANEL_TOO_SMALL ? 'visible' : 'hidden'
- const terminalDisabledClass = state.isConnected ? 'terminal-enabled' : 'terminal-disabled'
+ let terminalDisabledClass = 'terminal-enabled'
+ if (!state.isConnected || state.isNewFileDialogOpen) {
+ terminalDisabledClass = 'terminal-disabled'
+ }
+ // const terminalDisabledClass = state.isConnected ? 'terminal-enabled' : 'terminal-disabled'
return html`
+
+

+
${state.isConnected ? 'Connected to ' + state.connectedPort : ''}
+
+
emit('start-resizing-panel')}
onmouseup=${() => emit('stop-resizing-panel')}
@@ -25,6 +35,7 @@ function ReplPanel(state, emit) {
size: 'small',
onClick: onToggle
})}
+
${state.cache(XTerm, 'terminal').render()}
diff --git a/ui/arduino/views/components/toolbar.js b/ui/arduino/views/components/toolbar.js
index 70982b0..ad72a4f 100644
--- a/ui/arduino/views/components/toolbar.js
+++ b/ui/arduino/views/components/toolbar.js
@@ -12,64 +12,94 @@ function Toolbar(state, emit) {
const metaKeyString = state.platform === 'darwin' ? 'Cmd' : 'Ctrl'
return html`
-
${ConnectionDialog(state, emit)}
+ ${NewFileDialog(state, emit)}
`
}
diff --git a/ui/arduino/views/file-manager.js b/ui/arduino/views/file-manager.js
index eafdf65..fa43eff 100644
--- a/ui/arduino/views/file-manager.js
+++ b/ui/arduino/views/file-manager.js
@@ -1,5 +1,5 @@
function FileManagerView(state, emit) {
- let boardFullPath = 'Select a board...'
+ let boardFullPath = 'Connect to board'
let diskFullPath = `${state.diskNavigationRoot}${state.diskNavigationPath}`
if (state.isConnected) {
@@ -13,7 +13,7 @@ function FileManagerView(state, emit) {
${ConnectionDialog(state, emit)}
+ ${NewFileDialog(state, emit)}
`
}