Skip to content

Commit

Permalink
duo updater
Browse files Browse the repository at this point in the history
  • Loading branch information
Unreal-Dan committed Dec 13, 2024
1 parent 188da77 commit 8d6f07e
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 6 deletions.
28 changes: 28 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1933,3 +1933,31 @@ i {
}




.device-info {
display: flex;
align-items: center;
margin-bottom: 10px;
}

.device-info img {
width: 50px;
height: 50px;
margin-right: 10px;
}

#firmwareProgress {
margin-top: 10px;
height: 20px;
background-color: #e0e0e0;
border-radius: 10px;
overflow: hidden;
}

#firmwareProgressBar {
height: 100%;
background-color: #007bff;
width: 0;
transition: width 0.3s ease;
}
76 changes: 71 additions & 5 deletions js/ChromalinkPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,21 @@ export default class ChromalinkPanel extends Panel {
constructor(editor, modesPanel) {
const content = `
<div id="chromalinkOptions">
<button id="chromalinkFlash" class="chromalink-button">Flash Duo Firmware</button>
<div class="device-info">
<img src="./public/images/duo-logo-square-64.png" alt="Duo Icon" id="duoIcon" style="display:none;">
<div id="duoInfo" style="display:none;">
<p id="deviceUpdateLabel"><strong>Device:</strong> Duo</p>
<p id="deviceVersionLabel"><strong>Version:</strong> <span id="duoVersion"></span></p>
<p id="deviceLatestVersionLabel"><strong>Modes:</strong> <span id="duoModes"></span></p>
</div>
</div>
<button id="chromalinkFlash" class="chromalink-button" disabled>Flash Custom Firmware</button>
<button id="chromalinkUpdate" class="chromalink-button" disabled>Update Firmware</button>
<div class="progress-container">
<div id="firmwareProgress" class="progress-bar">
<div id="firmwareProgressBar"></div>
</div>
</div>
<input type="file" id="firmwareFileInput" style="display:none;" />
<button id="chromalinkConnect" class="chromalink-button">Connect Duo</button>
</div>
Expand All @@ -19,9 +33,14 @@ export default class ChromalinkPanel extends Panel {

initialize() {
const connectButton = document.getElementById('chromalinkConnect');
const flashButton = document.getElementById('chromalinkFlash');
const panelElement = document.getElementById('chromalinkPanel');
const firmwareFileInput = document.getElementById('firmwareFileInput');
const flashButton = document.getElementById('chromalinkFlash');
const updateButton = document.getElementById('chromalinkUpdate');

updateButton.addEventListener('click', async () => {
await this.updateFirmware();
});

// Connect button logic
connectButton.addEventListener('click', async () => {
Expand Down Expand Up @@ -54,7 +73,7 @@ export default class ChromalinkPanel extends Panel {
await this.vortexPort.flashFirmware(this.modesPanel.lightshow.vortexLib, firmwareData, (chunk, totalChunks) => {
// Update progress
const progress = Math.round((chunk / totalChunks) * 100);
Notification.success(`Writing firmware: ${progress}%...`);
progressBar.style.width = `${progress}%`;
});
// Call the vortexPort flash method
Notification.success('Firmware flashed successfully.');
Expand All @@ -71,14 +90,45 @@ export default class ChromalinkPanel extends Panel {
this.hide();
}

async updateFirmware() {
const progressBar = document.getElementById('firmwareProgressBar');
try {
Notification.success('Fetching latest firmware...');
// Fetch the firmware metadata
const apiResponse = await fetch('https://vortex.community/downloads/json/duo');
if (!apiResponse.ok) {
throw new Error('Failed to fetch firmware metadata');
}
const responseData = await apiResponse.json();
const firmwareUrl = responseData.firmware?.fileUrl;
const firmwareResponse = await fetch(firmwareUrl);
if (!firmwareResponse.ok) {
throw new Error('Failed to fetch firmware file.');
}
const firmwareData = new Uint8Array(await firmwareResponse.arrayBuffer());
Notification.success('Flashing firmware...');
await this.vortexPort.flashFirmware(
this.modesPanel.lightshow.vortexLib,
firmwareData,
(chunk, totalChunks) => {
const progress = Math.round((chunk / totalChunks) * 100);
progressBar.style.width = `${progress}%`;
}
);
Notification.success('Firmware updated successfully.');
} catch (error) {
Notification.failure('Firmware update failed: ' + error.message);
}
}

async connect() {
try {
// Use the connect function from VortexPort
this.duoHeader = await this.vortexPort.connectChromalink(this.modesPanel.lightshow.vortexLib);
if (!this.duoHeader) {
throw new Error('Failed to read Duo save header');
}
await this.modesPanel.checkVersion('Duo', this.duoHeader.version);
//await this.modesPanel.checkVersion('Duo', this.duoHeader.version);
const connectButton = document.getElementById('chromalinkConnect');
connectButton.innerHTML = 'Disconnect Duo'
this.isConnected = true;
Expand All @@ -89,8 +139,18 @@ export default class ChromalinkPanel extends Panel {
this.modesPanel.lightshow.vortex.clearModes();
this.modesPanel.lightshow.setLedCount(2);
this.modesPanel.updateSelectedDevice('Duo', true);
this.modesPanel.renderLedIndicators('Duo');
//this.modesPanel.renderLedIndicators('Duo');
this.modesPanel.selectAllLeds();
// update ui
document.getElementById('duoIcon').style.display = 'block';
document.getElementById('duoInfo').style.display = 'block';
document.getElementById('duoVersion').textContent = this.duoHeader.version;
document.getElementById('duoModes').textContent = this.duoHeader.numModes;
const flashButton = document.getElementById('chromalinkFlash');
const updateButton = document.getElementById('chromalinkUpdate');
flashButton.disabled = false;
updateButton.disabled = false;
// give a notification
Notification.success('Successfully Chromalinked Duo v' + this.duoHeader.version);
} catch (error) {
Notification.failure('Failed to connect: ' + error.message);
Expand All @@ -112,6 +172,12 @@ export default class ChromalinkPanel extends Panel {
this.modesPanel.updateSelectedDevice('Chromadeck', true);
this.modesPanel.renderLedIndicators('Chromadeck');
this.modesPanel.selectAllLeds();
const flashButton = document.getElementById('chromalinkFlash');
const updateButton = document.getElementById('chromalinkUpdate');
flashButton.disabled = true;
updateButton.disabled = true;
document.getElementById('duoIcon').style.display = 'none';
document.getElementById('duoInfo').style.display = 'none';
Notification.success('Successfully Disconnected Chromalink');
} catch (error) {
Notification.failure('Failed to connect: ' + error.message);
Expand Down
5 changes: 4 additions & 1 deletion js/VortexPort.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,6 @@ export default class VortexPort {
// Call the Wasm function
let headerStream = new vortexLib.ByteStream();
vortexLib.createByteStreamFromRawData(header, headerStream);
// TODO: big header is 15 not 5
if (!headerStream.checkCRC() || headerStream.size() < 5) {
throw new Error('Bad CRC or size: ' + headerStream.size());
}
Expand All @@ -561,6 +560,10 @@ export default class VortexPort {
duoHeader.flags = headerData[2];
duoHeader.brightness = headerData[3];
duoHeader.numModes = headerData[4];
if (headerStream.size() > 5) {
duoHeader.vBuild = headerData[5];
}
console.log(JSON.stringify(headerData));
// construct a full version string
duoHeader.version = duoHeader.vMajor + '.' + duoHeader.vMinor + '.' + duoHeader.vBuild;
duoHeader.rawData = headerData;
Expand Down

0 comments on commit 8d6f07e

Please sign in to comment.