chore: prettier format all files, brotli, Sentry release tagging, CI gates
CI / Build & Quality Checks (push) Failing after 5m12s
CI / Build & Quality Checks (push) Failing after 5m12s
Prettier: auto-formatted 103 files to fix baseline. Prettier check in CI is now a hard gate (removed continue-on-error). Brotli: installed libnginx-mod-http-brotli-filter/static. Enabled in nginx with brotli_static on for pre-compressed assets and comp_level 6. Sentry releases: deploy script now exports VITE_APP_VERSION=<git-short-sha> before building so each Sentry release maps to an exact commit. CI also passes github.sha as VITE_APP_VERSION. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -62,7 +62,9 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
|
||||
// Track microphone via ref so the PTT effect doesn't need it as a dep (avoids listener churn)
|
||||
const microphoneRef = useRef(microphone);
|
||||
useEffect(() => { microphoneRef.current = microphone; }, [microphone]);
|
||||
useEffect(() => {
|
||||
microphoneRef.current = microphone;
|
||||
}, [microphone]);
|
||||
|
||||
// Handle PTT mode toggle mid-call — save/restore mic state (I-4)
|
||||
const pttModeRef = useRef(pttMode);
|
||||
@@ -165,8 +167,8 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
setPttActive(false);
|
||||
}
|
||||
};
|
||||
// microphone intentionally read via microphoneRef — excluded from deps to avoid listener churn
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// microphone intentionally read via microphoneRef — excluded from deps to avoid listener churn
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pttMode, pttKey, callEmbed]);
|
||||
|
||||
const [hangupState, hangup] = useAsyncCallback(
|
||||
@@ -184,21 +186,31 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
justifyContent="Center"
|
||||
alignItems="Center"
|
||||
>
|
||||
{pttMode && (
|
||||
lotusTerminal ? (
|
||||
<Box style={{
|
||||
position: 'absolute',
|
||||
top: '-2.5rem',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
background: pttActive ? 'rgba(0,255,136,0.18)' : 'rgba(255,107,0,0.12)',
|
||||
border: `1px solid ${pttActive ? 'rgba(0,255,136,0.55)' : 'rgba(255,107,0,0.35)'}`,
|
||||
borderRadius: '99px',
|
||||
padding: '0.2rem 0.9rem',
|
||||
pointerEvents: 'none',
|
||||
whiteSpace: 'nowrap',
|
||||
}}>
|
||||
<Text size="T200" style={{ color: pttActive ? '#00FF88' : '#FF6B00', fontWeight: 700, letterSpacing: '0.08em', fontFamily: 'JetBrains Mono, monospace' }}>
|
||||
{pttMode &&
|
||||
(lotusTerminal ? (
|
||||
<Box
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '-2.5rem',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
background: pttActive ? 'rgba(0,255,136,0.18)' : 'rgba(255,107,0,0.12)',
|
||||
border: `1px solid ${pttActive ? 'rgba(0,255,136,0.55)' : 'rgba(255,107,0,0.35)'}`,
|
||||
borderRadius: '99px',
|
||||
padding: '0.2rem 0.9rem',
|
||||
pointerEvents: 'none',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
size="T200"
|
||||
style={{
|
||||
color: pttActive ? '#00FF88' : '#FF6B00',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.08em',
|
||||
fontFamily: 'JetBrains Mono, monospace',
|
||||
}}
|
||||
>
|
||||
{pttActive ? '● LIVE' : `PTT — Hold ${pttKeyLabel}`}
|
||||
</Text>
|
||||
</Box>
|
||||
@@ -221,8 +233,7 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
{pttActive ? '● Live' : `PTT — Hold ${pttKeyLabel}`}
|
||||
</Text>
|
||||
</Chip>
|
||||
)
|
||||
)}
|
||||
))}
|
||||
{shareConfirm && (
|
||||
<Box
|
||||
style={{
|
||||
@@ -242,17 +253,31 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
gap: '0.75rem',
|
||||
}}
|
||||
>
|
||||
<Text size="T300" style={{ fontWeight: 600 }}>Share your screen?</Text>
|
||||
<Text size="T200" style={{ opacity: 0.75 }}>Your screen will be visible to all participants in this call.</Text>
|
||||
<Text size="T300" style={{ fontWeight: 600 }}>
|
||||
Share your screen?
|
||||
</Text>
|
||||
<Text size="T200" style={{ opacity: 0.75 }}>
|
||||
Your screen will be visible to all participants in this call.
|
||||
</Text>
|
||||
<Box gap="200">
|
||||
<Button
|
||||
size="300" variant="Success" fill="Solid" radii="300"
|
||||
onClick={() => { callEmbed.control.toggleScreenshare(); setShareConfirm(false); }}
|
||||
size="300"
|
||||
variant="Success"
|
||||
fill="Solid"
|
||||
radii="300"
|
||||
onClick={() => {
|
||||
callEmbed.control.toggleScreenshare();
|
||||
setShareConfirm(false);
|
||||
}}
|
||||
>
|
||||
<Text size="B300">Share</Text>
|
||||
</Button>
|
||||
<Button
|
||||
size="300" variant="Secondary" fill="Soft" radii="300" outlined
|
||||
size="300"
|
||||
variant="Secondary"
|
||||
fill="Soft"
|
||||
radii="300"
|
||||
outlined
|
||||
onClick={() => setShareConfirm(false)}
|
||||
>
|
||||
<Text size="B300">Cancel</Text>
|
||||
@@ -281,9 +306,8 @@ export function CallControls({ callEmbed }: CallControlsProps) {
|
||||
<VideoButton enabled={video} onToggle={() => callEmbed.control.toggleVideo()} />
|
||||
<ScreenShareButton
|
||||
enabled={screenshare}
|
||||
onToggle={() => screenshare
|
||||
? callEmbed.control.toggleScreenshare()
|
||||
: setShareConfirm(true)
|
||||
onToggle={() =>
|
||||
screenshare ? callEmbed.control.toggleScreenshare() : setShareConfirm(true)
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
Reference in New Issue
Block a user