-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: connect dialog for micropython (#21)
- Loading branch information
Showing
6 changed files
with
175 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
src/lib/components/core/popups/popups/PythonUploader.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
<script lang="ts"> | ||
import { _ } from "svelte-i18n"; | ||
import Button from "$components/ui/Button.svelte"; | ||
import ProgressBar from "$components/ui/ProgressBar.svelte"; | ||
import { type PopupState, popups } from "$state/popup.svelte"; | ||
import { usbRequest } from "$state/upload.svelte"; | ||
import { | ||
Prompt, | ||
SUPPORTED_VENDOR_IDS, | ||
installed, | ||
port, | ||
robot, | ||
} from "$state/workspace.svelte"; | ||
import { getContext, onMount } from "svelte"; | ||
import type { Writable } from "svelte/store"; | ||
import type MicroPythonIO from "../../../../micropython"; | ||
interface Props { | ||
io: MicroPythonIO; | ||
} | ||
const popupState = getContext<Writable<PopupState>>("state"); | ||
const { io }: Props = $props(); | ||
let progress = $state(0); | ||
let currentState = $state("CONNECTING"); | ||
let error = $state<string | null>(null); | ||
let done = $state(false); | ||
class UploadError extends Error { | ||
constructor( | ||
public name: string, | ||
public description: string, | ||
) { | ||
super(); | ||
} | ||
} | ||
async function upload(res: Record<string, string>) { | ||
try { | ||
await port.reserve(); | ||
await $robot.programmer.upload($port, res); | ||
} catch (e) { | ||
console.log(e); | ||
throw new UploadError("UPDATE_FAILED", e); | ||
} | ||
port.release(); | ||
} | ||
onMount(async () => { | ||
try { | ||
const installed = await io.enterREPLMode(); | ||
progress += 100 / 5; | ||
currentState = "DOWNLOADING_FIRMWARE"; | ||
let firmware: Record<string, string>; | ||
if (!installed) firmware = await io.getFirmware(); | ||
progress += 100 / 5; | ||
currentState = "UPLOADING_FIRMWARE"; | ||
if (!installed) await upload(firmware); | ||
progress += 100 / 5; | ||
currentState = "CONNECTING"; | ||
if (!installed) await io.enterREPLMode(); | ||
progress += 100 / 5; | ||
currentState = "INSTALLING_LIBRARIES"; | ||
await io.packageManager.flashLibrary( | ||
"github:leaphy-robotics/leaphy-micropython/package.json", | ||
); | ||
progress += 100 / 5; | ||
popups.close($popupState.id); | ||
} catch (e) { | ||
done = true; | ||
currentState = "UPLOAD_FAILED"; | ||
error = e.description; | ||
} | ||
}); | ||
function close() { | ||
popups.close($popupState.id); | ||
} | ||
async function connectUSB() { | ||
const [device] = await navigator.usb.getDevices(); | ||
if (device) return usbRequest.respond(device); | ||
usbRequest.respond( | ||
await navigator.usb.requestDevice({ | ||
filters: SUPPORTED_VENDOR_IDS.map((vendor) => ({ | ||
vendorId: vendor, | ||
})), | ||
}), | ||
); | ||
} | ||
</script> | ||
|
||
<div class="content" class:error={!!error}> | ||
{#if $usbRequest} | ||
<h2 class="state">{$_("RECONNECT")}</h2> | ||
<div class="info">{$_("RECONNECT_INFO")}</div> | ||
<Button name={"Reconnect"} mode={"primary"} onclick={connectUSB} /> | ||
{:else} | ||
<h2 class="state">{$_(currentState)}</h2> | ||
|
||
{#if error} | ||
<code class="error-result">{error}</code> | ||
{/if} | ||
{#if done} | ||
<Button | ||
name={"Go back to editor"} | ||
mode={"primary"} | ||
onclick={close} | ||
/> | ||
{:else} | ||
<ProgressBar {progress} /> | ||
{/if} | ||
{/if} | ||
</div> | ||
|
||
<style> | ||
h2 { | ||
margin: 0; | ||
} | ||
.content { | ||
display: flex; | ||
flex-direction: column; | ||
padding: 20px; | ||
gap: 20px; | ||
justify-content: center; | ||
align-items: center; | ||
min-width: 400px; | ||
max-width: 80vw; | ||
min-height: 200px; | ||
max-height: 80vh; | ||
} | ||
.state { | ||
font-weight: bold; | ||
} | ||
.error h2 { | ||
color: red; | ||
} | ||
.error-result { | ||
background: var(--secondary); | ||
border-radius: 5px; | ||
padding: 10px; | ||
color: red; | ||
} | ||
</style> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters