mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-17 01:50:47 -04:00
wawea
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||||
<title>Multi Roomba Rover</title>
|
<title>Multi Roomba Rover</title>
|
||||||
<script type="module" crossorigin src="/assets/index-ByOAIc0r.js"></script>
|
<script type="module" crossorigin src="/assets/index-8-JHgslZ.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-B-TLXecO.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-B-TLXecO.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { fieldClass } from './constants.js';
|
import { fieldClass } from './constants.js';
|
||||||
import { useControlSystem } from '../../controls/index.js';
|
import { useControlSystem } from '../../controls/index.js';
|
||||||
|
import { formatKeyLabel } from '../../controls/keymapUtils.js';
|
||||||
import { useSettingsNamespace } from '../../settings/index.js';
|
import { useSettingsNamespace } from '../../settings/index.js';
|
||||||
|
|
||||||
const MAX_UPLOAD_BYTES = 8 * 1024 * 1024;
|
const MAX_UPLOAD_BYTES = 8 * 1024 * 1024;
|
||||||
@@ -168,6 +169,11 @@ function StatusIndicator({ label, active, detail = '' }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function KeyPill({ label }) {
|
||||||
|
if (!label) return null;
|
||||||
|
return <span className="rounded border border-white/40 px-1 text-[0.7rem] text-white">{label}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
function mergeFloatChunks(chunks) {
|
function mergeFloatChunks(chunks) {
|
||||||
const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
||||||
const merged = new Float32Array(total);
|
const merged = new Float32Array(total);
|
||||||
@@ -284,6 +290,7 @@ export default function VipAudioUploadCard({
|
|||||||
const whipLinkActive = !clipMode && (micState === 'live' || micState === 'starting');
|
const whipLinkActive = !clipMode && (micState === 'live' || micState === 'starting');
|
||||||
const clipRecording = clipMode && clipState === 'recording';
|
const clipRecording = clipMode && clipState === 'recording';
|
||||||
const clipSending = clipMode && clipState === 'sending';
|
const clipSending = clipMode && clipState === 'sending';
|
||||||
|
const pttKeyLabel = formatKeyLabel(controlState?.keymap?.micPtt?.[0]) || 'M';
|
||||||
|
|
||||||
const setPttMode = useCallback(
|
const setPttMode = useCallback(
|
||||||
(nextMode) => {
|
(nextMode) => {
|
||||||
@@ -733,12 +740,19 @@ export default function VipAudioUploadCard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-0.5">
|
<div className="grid gap-0.5">
|
||||||
|
<section className="surface">
|
||||||
|
<div className="flex items-center justify-center gap-0.5 py-0.25 text-xs text-slate-300">
|
||||||
|
<span>Push-to-Talk Key</span>
|
||||||
|
<KeyPill label={pttKeyLabel} />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div className="grid gap-0.5 grid-cols-1 lg:grid-cols-2">
|
<div className="grid gap-0.5 grid-cols-1 lg:grid-cols-2">
|
||||||
<section className="surface h-full">
|
<section className="surface h-full">
|
||||||
<div className="grid h-full gap-0.5 grid-rows-[auto_auto_1fr]">
|
<div className="grid h-full gap-0.5 grid-rows-[auto_auto_1fr]">
|
||||||
<p className="text-sm text-slate-200 text-center">PTT Mode</p>
|
<p className="text-sm text-slate-200 text-center">PTT Mode</p>
|
||||||
<p className="text-xs text-slate-400 text-center">
|
<p className="text-xs text-slate-400 text-center">
|
||||||
Choose how holding your PTT key behaves: live mic stream, or record-and-send clip.
|
Choose how holding your PTT key behaves: live mic stream, or record-and-send clip. If the live stream doesn't work, switch to clip mode.
|
||||||
</p>
|
</p>
|
||||||
<div className="grid grid-cols-2 gap-0.5">
|
<div className="grid grid-cols-2 gap-0.5">
|
||||||
<button
|
<button
|
||||||
@@ -826,7 +840,7 @@ export default function VipAudioUploadCard({
|
|||||||
<div className="grid gap-0.5 content-start">
|
<div className="grid gap-0.5 content-start">
|
||||||
<StatusIndicator label="WHIP link" active={whipLinkActive} detail={micState} />
|
<StatusIndicator label="WHIP link" active={whipLinkActive} detail={micState} />
|
||||||
<StatusIndicator label="Mic hot" active={micHot} detail={micHot ? 'transmitting' : 'muted'} />
|
<StatusIndicator label="Mic hot" active={micHot} detail={micHot ? 'transmitting' : 'muted'} />
|
||||||
<div className="surface-muted text-center text-xs text-slate-400">PTT key: {controlState?.keymap?.micPtt?.[0] || 'm'} (hold)</div>
|
<div className="surface-muted text-center text-xs text-slate-400">Hold <KeyPill label={pttKeyLabel} /> to talk</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user