Add serial number display

This commit is contained in:
daylily
2025-04-05 02:20:17 -04:00
parent 20a21c4650
commit 0583d648aa
4 changed files with 70 additions and 23 deletions
+10 -3
View File
@@ -1,17 +1,24 @@
<script lang="ts">
import type { PopoverTriggerProps } from 'bits-ui'
import type { Snippet } from 'svelte'
import IconInfo from '~icons/material-symbols/info'
import * as Popover from '$lib/components/ui/popover'
interface Props extends PopoverTriggerProps {}
interface Props extends PopoverTriggerProps {
icon?: Snippet
}
const { children, ...restProps }: Props = $props()
const { icon, children, ...restProps }: Props = $props()
</script>
<Popover.Root>
<Popover.Trigger aria-label="More info" {...restProps}>
<IconInfo class="text-muted-foreground text-sm" aria-hidden />
{#if !icon}
<IconInfo class="text-muted-foreground text-sm" aria-hidden />
{:else}
{@render icon()}
{/if}
</Popover.Trigger>
<Popover.Content class="text-sm">
+18 -6
View File
@@ -27,16 +27,16 @@ export function createDeviceContext(): DeviceContext {
function connectIfIdle(e: HIDConnectionEvent) {
if (!isInkclip(e.device) || ctx.device !== null) return
toast.info('Device connected')
ctx.device = e.device
}
toast.info('Device connected')
ctx.device = e.device
}
function disconnectIfSame(e: HIDConnectionEvent) {
if (ctx.device !== e.device) return
toast.info('Device disconnected')
ctx.device = null
}
toast.info('Device disconnected')
ctx.device = null
}
navigator.hid.addEventListener('connect', connectIfIdle)
navigator.hid.addEventListener('disconnect', disconnectIfSame)
@@ -48,3 +48,15 @@ export function createDeviceContext(): DeviceContext {
return setContext(DeviceContextToken, ctx)
}
export async function tryOpenDevice(device: HIDDevice): Promise<boolean> {
if (device.opened) return true
try {
await device.open()
return true
} catch (e) {
toast.error(`Unable to open device: ${e}`)
return false
}
}
+39 -3
View File
@@ -3,9 +3,40 @@
import IconCheckCircle from '~icons/material-symbols/check-circle'
import ConnectButton from './ConnectButton.svelte'
import { getDeviceContext } from '$lib/contexts/device.svelte'
import { getDeviceContext, tryOpenDevice } from '$lib/contexts/device.svelte'
import MoreInfo from '$lib/components/MoreInfo.svelte'
const deviceCtx = getDeviceContext()
let serial = $state('[Retrieving...]')
async function updateSerial() {
if (deviceCtx.device === null) {
serial = '[Retrieving...]'
return
}
if (!(await tryOpenDevice(deviceCtx.device))) {
serial = '[Error]'
return
}
function setSerial(e: HIDInputReportEvent) {
if (e.reportId !== 0x02) return
serial = String.fromCharCode(...Array.from(new Uint8Array(e.data.buffer)))
}
let updated = false
deviceCtx.device.addEventListener('inputreport', e => {
if (!updated) setSerial(e)
updated = true
})
deviceCtx.device.sendReport(0x02, new Uint8Array(1))
}
$effect(() => {
updateSerial()
})
</script>
<section class="row gap-2 max-lg:stack max-lg:items-stretch" aria-labelledby="connect-section-label">
@@ -17,8 +48,13 @@
<IconPending aria-hidden /> Not connected to any device yet. Plug in your device, and click on the button to select
it.
{:else}
<IconCheckCircle aria-hidden /> Successfully conected to device. If you want to, you can connect to another device
instead.
<MoreInfo>
{#snippet icon()}
<IconCheckCircle aria-hidden />
{/snippet}
The serial ID of this device is <code>{serial}</code>.
</MoreInfo>
Successfully conected to device. If you want to, you can connect to another device instead.
{/if}
</div>
</div>
+3 -11
View File
@@ -2,7 +2,7 @@
import { Button } from '$lib/components/ui/button'
import { toast } from 'svelte-sonner'
import { getDeviceContext } from '$lib/contexts/device.svelte'
import { getDeviceContext, tryOpenDevice } from '$lib/contexts/device.svelte'
import { getRenderedContext } from '$lib/contexts/rendered.svelte'
import { BYTES_IN_A_ROW, DEVICE_HEIGHT, DEVICE_WIDTH, WRITE_TIME } from '$lib/constants'
@@ -22,15 +22,7 @@
async function connectAndWrite() {
if (deviceCtx.device === null || renderedCtx.rendered === null) return
if (!deviceCtx.device.opened) {
try {
await deviceCtx.device.open()
} catch (e) {
toast.error(`Unable to open device: ${e}`)
return
}
}
if (!(await tryOpenDevice(deviceCtx.device))) return
const buffer = new Uint8Array(DEVICE_HEIGHT * BYTES_IN_A_ROW)
for (let y = 0; y < DEVICE_HEIGHT; y++) {
@@ -47,7 +39,7 @@
inProgress = true
try {
await deviceCtx.device.sendReport(0, buffer)
await deviceCtx.device.sendReport(0x01, buffer)
} catch (e) {
toast.error(`Error writing to device: ${e}`)
return