Skip to content

Register app scheme on Windows and Linux #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions css/status-bar.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
transition: max-height 0.5s ease, padding 0.5s ease, opacity 0.3s ease;
}

.status-bar .close-button {
cursor: pointer;
}

.status-bar.visible {
display: flex;
max-height: 480px;
Expand Down
8 changes: 7 additions & 1 deletion forge.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ module.exports = {
ignore: filesToExclude,
prune: true,
derefSymlinks: true,
protocols: [ {
protocols: [ {
// Register custom URL scheme on macOS
name: 'micropython-package-installer',
schemes: ['micropython-package-installer']
}],
Expand Down Expand Up @@ -134,6 +135,11 @@ module.exports = {
{
name: '@electron-forge/maker-deb',
platforms: ['linux'],
config: {
options: {
mimeType: ['x-scheme-handler/micropython-package-installer']
}
}
},
],
publishers: [
Expand Down
6 changes: 6 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ <h2>Packages</h2>
<div id="status-bar" class="status-bar hidden">
<span id="status-message"></span>
<div class="loading-spinner small hidden"></div>
<div id="status-bar-close" class="close-button">
<!-- Close button SVG -->
<svg id="close-icon" width="10" height="10" viewBox="0 0 10 10" fill="#eee" xmlns="http://www.w3.org/2000/svg">
<path d="M10 0.707107L9.29289 0L5 4.29289L0.707107 0L0 0.707107L4.29289 5L0 9.29289L0.707107 10L5 5.70711L9.29289 10L10 9.29289L5.70711 5L10 0.707107Z" fill="#eee"/>
</svg>
</div>
</div>

<!-- Divider -->
Expand Down
18 changes: 13 additions & 5 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@ if (require('electron-squirrel-startup')) return;
const { app, BrowserWindow, ipcMain, shell } = require('electron');
const path = require('path');

const APP_SCHEME_NAME = 'micropython-package-installer';
const ARDUINO_VID = 0x2341;

// Handle events from windows squirrel installer
if (process.platform === "win32" && handleSquirrelEvent()) {
// squirrel event handled and app will exit in 1000ms, so don't do anything else
return;
}

// On macOS the scheme is already registered through the app bundle metadata
// but on Windows and Linux we need to register it manually
if (process.platform !== "darwin" && !app.isDefaultProtocolClient(APP_SCHEME_NAME)) {
if(!app.setAsDefaultProtocolClient(APP_SCHEME_NAME)) {
console.error('Failed to register custom URL scheme', APP_SCHEME_NAME);
}
}

const { updateElectronApp } = require('update-electron-app')
updateElectronApp()

let mainWindow;
let upyPackage;
let packageManager;
let deviceManager;
const ARDUINO_VID = 0x2341;

function createWindow() {
mainWindow = new BrowserWindow({
Expand Down Expand Up @@ -45,9 +55,7 @@ app.on('ready', async() => {
});

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
app.quit();
});

app.on('activate', () => {
Expand Down Expand Up @@ -95,7 +103,7 @@ ipcMain.handle('install-package', async (event, aPackage, serialPort, compileFil
return { success: true };
} catch (error) {
let packageDesignator = aPackage.name || aPackage.url;
console.error(`Failed to install package ${packageDesignator}:`, error);
console.error(`Failed to install package ${packageDesignator}:`, error.message);

// Check if error contains "Resource busy" and return a more user-friendly message
if(error.message.includes('Resource busy') || error.message.includes('Access denied')) {
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "micropython-package-installer",
"version": "1.0.0",
"version": "1.0.1-beta.1",
"description": "A tool to install MicroPython packages onto supported Arduino boards.",
"main": "main.js",
"scripts": {
Expand Down Expand Up @@ -40,6 +40,6 @@
"dependencies": {
"electron-squirrel-startup": "^1.0.1",
"update-electron-app": "^3.0.0",
"upy-package": "github:arduino/upy-package#v1.0.0"
"upy-package": "github:arduino/upy-package#v1.0.1"
}
}
12 changes: 9 additions & 3 deletions renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ let customURLplaceholders = ['github:janedoe/button-mpy',
];

const statusBar = document.getElementById('status-bar');
const statusBarCloseButton = document.getElementById('status-bar-close');
const statusMessage = document.getElementById('status-message');
const deviceSelectionList = document.querySelector(".item-selection-list");
const reloadDeviceListLink = document.getElementById("reload-link");
Expand Down Expand Up @@ -52,6 +53,8 @@ document.addEventListener('DOMContentLoaded', async () => {
setInstallButtonsEnabled(true);
});

statusBarCloseButton.addEventListener('click', hideStatus);

reloadDeviceListLink.addEventListener('click', async () => {
await reloadDeviceList();
});
Expand Down Expand Up @@ -248,6 +251,8 @@ function toggleUserInteraction(enabled) {
searchField.disabled = !enabled;
githubUrlInput.disabled = !enabled;
manualInstallButton.disabled = !enabled;
compileFilesCheckbox.disabled = !enabled;
overwriteExistingCheckbox.disabled = !enabled;
reloadDeviceListLink.style.pointerEvents = enabled ? 'auto' : 'none';
boardItems.forEach(board => board.style.pointerEvents = enabled ? 'auto' : 'none');

Expand Down Expand Up @@ -335,6 +340,9 @@ function showStatus(message, displayLoader = false, duration = null) {
statusMessage.textContent = message;
statusBar.classList.remove('hidden');
statusBarLoadingSpinner.classList.toggle('hidden', !displayLoader);

// Hide close button when loader is displayed
statusBarCloseButton.classList.toggle('hidden', displayLoader);

// Add the visible class to trigger the slide down effect
setTimeout(() => {
Expand All @@ -348,14 +356,12 @@ function showStatus(message, displayLoader = false, duration = null) {
}

function hideStatus() {
const statusBar = document.getElementById('status-bar');

// Remove the visible class to trigger the slide-up effect
statusBar.classList.remove('visible');

// After the transition ends, hide the element
setTimeout(() => {
statusBar.style.display = 'none';
statusBar.classList.add('hidden');
}, 500); // Match this duration with the CSS transition duration
}

Expand Down