|
1 |
| -import { firmwareOptions } from '../constants' |
| 1 | +import { FirmwareOption } from '../constants' |
2 | 2 | import { DeviceService } from './DeviceService';
|
3 | 3 |
|
4 | 4 | export class FirmwareService {
|
5 | 5 | private firmwareString: string | null = null;
|
6 | 6 | private firmwareBlob: Blob | null = null;
|
7 | 7 | private selectedFirmwareId: string = 'Auto';
|
| 8 | + // Should make firmwareOptions a private variable and use getters to access it. |
| 9 | + // This way we can add logic to the getters if we need to in the future. Default to empty record. |
| 10 | + private firmwareOptions: Record<string, FirmwareOption> = {}; |
8 | 11 |
|
9 | 12 | constructor(private deviceService: DeviceService) {
|
10 | 13 | const savedSelection = localStorage.getItem('selectedFirmwareId');
|
| 14 | + // Get the firmware options from GitHub (or local files). |
| 15 | + // Maybe we'll add an explicit button for updating the firmware options in the future... |
| 16 | + // We'll initialize our private firmwareOptions here with the reqFirmwareOptionsGitHub() method. |
| 17 | + this.reqFirmwareOptionsGitHub().then((res) => { |
| 18 | + this.firmwareOptions = res; |
| 19 | + }) |
| 20 | + |
11 | 21 | if (savedSelection) {
|
12 | 22 | this.selectedFirmwareId = savedSelection;
|
13 | 23 | } else {
|
14 | 24 | this.selectedFirmwareId = 'auto';
|
15 | 25 | }
|
16 | 26 | }
|
17 | 27 |
|
18 |
| - getFirmwareOptions(){ |
| 28 | + // We'll use this method to fetch the firmware options from GitHub. |
| 29 | + // We could alternatively use local files in ../binaries/ so we aren't sending a request to GitHub every time. |
| 30 | + private async reqFirmwareOptionsGitHub(): Promise<Record<string, FirmwareOption>> { |
| 31 | + const releases = await fetch('https://api.github.com/repos/sparkfun/micropython/releases', { |
| 32 | + method: 'GET' |
| 33 | + }); |
| 34 | + |
| 35 | + if (!releases.ok) { |
| 36 | + throw new Error(`Failed to fetch releases: ${releases.status} ${releases.statusText}`); |
| 37 | + } |
| 38 | + const releasesData = await releases.json(); |
| 39 | + const firmwareOptions: Record<string, FirmwareOption> = {}; |
| 40 | + |
| 41 | + firmwareOptions['auto'] = { |
| 42 | + name: 'Auto detection', |
| 43 | + url: '' |
| 44 | + }; |
| 45 | + |
| 46 | + // Take the first release and iterate through the assets to populate the firmware options. |
| 47 | + const latestRelease = releasesData[0]; |
| 48 | + if (latestRelease && latestRelease.assets) { |
| 49 | + latestRelease.assets.forEach((asset: any) => { |
| 50 | + // We should make the name the full name of the asset but the key the firmwareId (the board name in lowercase with dashes and an optional "m" prefix for minimal). |
| 51 | + const firmwareName = asset.name; |
| 52 | + var firmwareId = firmwareName.replace(/\.uf2|\.zip/g, '').toLowerCase().replace(/_/g, '-'); |
| 53 | + |
| 54 | + if (firmwareName.startsWith('MINIMAL_')) { |
| 55 | + firmwareId = 'm-' + firmwareId.replace('minimal-', ''); |
| 56 | + } |
| 57 | + const firmwareUrl = asset.browser_download_url; |
| 58 | + |
| 59 | + const firmwareOption: FirmwareOption = { |
| 60 | + name: firmwareName, |
| 61 | + url: firmwareUrl |
| 62 | + }; |
| 63 | + firmwareOptions[firmwareId] = firmwareOption; |
| 64 | + }); |
| 65 | + } |
| 66 | + |
| 67 | + // Add the local firmware option. |
| 68 | + firmwareOptions['local'] = { |
| 69 | + name: 'Local firmware upload', |
| 70 | + url: '' |
| 71 | + }; |
| 72 | + |
19 | 73 | return firmwareOptions;
|
20 | 74 | }
|
21 | 75 |
|
| 76 | + // This is where we can add our logic of fetching from GitHub. |
| 77 | + // We could alternatively use local files in ../binaries/ so we aren't sending a request to GitHub every time. |
| 78 | + getFirmwareOptions(){ |
| 79 | + return this.firmwareOptions; |
| 80 | + } |
| 81 | + |
22 | 82 | getSelectedFirmwareId(): string {
|
23 | 83 | return this.selectedFirmwareId;
|
24 | 84 | }
|
25 | 85 |
|
26 | 86 | setSelectedFirmwareId(id: string): void {
|
27 |
| - if (id in firmwareOptions){ |
| 87 | + if (id in this.firmwareOptions) { |
28 | 88 | this.selectedFirmwareId = id;
|
29 | 89 | this.firmwareString = null;
|
30 | 90 | this.firmwareBlob = null;
|
@@ -67,8 +127,9 @@ export class FirmwareService {
|
67 | 127 | return this.downloadSpecificFirmware(firmwareId);
|
68 | 128 | }
|
69 | 129 |
|
| 130 | + // TODO: This is where we can add our logic of fetching from GitHub |
70 | 131 | private async downloadSpecificFirmware(firmwareId: string): Promise<string> {
|
71 |
| - const selectedFirmware = firmwareOptions[firmwareId] |
| 132 | + const selectedFirmware = this.firmwareOptions[firmwareId] |
72 | 133 | if (!selectedFirmware || !selectedFirmware.url) {
|
73 | 134 | throw new Error(`Invalid firmware selection or no URL for: ${firmwareId}`);
|
74 | 135 | }
|
|
0 commit comments