Compare commits

...

2 Commits

Author SHA1 Message Date
jared 4e6b045c57 ui: incoming call button hierarchy + EventReaders timestamp glow
CI / Build & Quality Checks (push) Successful in 10m24s
- IncomingCall: Reject uses variant=Critical (red), Ignore uses variant=Secondary
  — previously both were variant=Success (green), making them visually identical
  to the Answer button
- EventReaders: TDS timestamp glow reduced from double-layer to single-layer
  (was 0 0 6px + 0 0 14px, now just 0 0 5px at 0.45 opacity)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:34:55 -04:00
jared 928c796316 ui: voice recorder pulse + TDS styling, wire mic denied error to input bar
- VoiceMessageRecorder recording dot now pulses (reuses pttLivePulse keyframe)
- Added data-voice-recorder / data-voice-rec-dot / data-voice-waveform attributes
  for TDS targeting: green pulsing dot, cyan waveform bars, subtle border in TDS dark
- Wire VoiceMessageRecorder onError to the same input-bar error display used by
  location errors (mic denied, media error surfaces to user instead of silent fail)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 00:30:12 -04:00
5 changed files with 42 additions and 3 deletions
+1 -1
View File
@@ -235,7 +235,7 @@ function IncomingCall({ dm, info, onIgnore, onAnswer, onReject }: IncomingCallPr
</Button>
<Button
style={{ flexGrow: 1 }}
variant="Success"
variant={dm ? 'Critical' : 'Secondary'}
fill="Soft"
size="400"
radii="400"
@@ -185,6 +185,7 @@ export function VoiceMessageRecorder({ onSend, onError }: VoiceRecorderProps) {
if (state === 'recording') {
return (
<Box
data-voice-recorder="recording"
alignItems="Center"
gap="200"
style={{
@@ -194,18 +195,21 @@ export function VoiceMessageRecorder({ onSend, onError }: VoiceRecorderProps) {
}}
>
<Box
data-voice-rec-dot
style={{
width: toRem(8),
height: toRem(8),
borderRadius: '50%',
background: 'var(--tc-danger-normal)',
flexShrink: 0,
animation: 'pttLivePulse 900ms ease-in-out infinite',
}}
/>
<Text size="T200" style={{ minWidth: toRem(32), fontVariantNumeric: 'tabular-nums' }}>
{formatDuration(durationMs)}
</Text>
<Box
data-voice-waveform
alignItems="Center"
gap="100"
style={{ height: toRem(20), overflow: 'hidden', flexShrink: 0 }}
@@ -145,7 +145,7 @@ export const EventReaders = as<'div', EventReadersProps>(
lotusTerminal
? {
color: '#FFB300',
textShadow: '0 0 6px #FFB300, 0 0 14px rgba(255,179,0,0.40)',
textShadow: '0 0 5px rgba(255,179,0,0.45)',
fontSize: '0.72rem',
}
: { opacity: 0.6 }
+7 -1
View File
@@ -902,7 +902,13 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
<Icon src={Icons.SpaceGlobe} size="100" />
)}
</IconButton>
<VoiceMessageRecorder onSend={handleVoiceSend} />
<VoiceMessageRecorder
onSend={handleVoiceSend}
onError={(err) => {
setLocationError(err);
setTimeout(() => setLocationError(null), 4000);
}}
/>
<IconButton
onClick={submit}
variant="SurfaceVariant"
+29
View File
@@ -921,6 +921,35 @@ globalStyle(
},
);
// ── Voice recorder TDS ───────────────────────────────────────────────────────
globalStyle(`body.${lotusTerminalBodyClass} [data-voice-recorder="recording"]`, {
background: 'rgba(0,212,255,0.05) !important' as any,
border: '1px solid rgba(0,212,255,0.22) !important' as any,
borderRadius: '6px',
});
globalStyle(`body.${lotusTerminalBodyClass} [data-voice-rec-dot]`, {
background: '#00FF88 !important' as any,
boxShadow: '0 0 6px rgba(0,255,136,0.55)',
});
globalStyle(`body.${lotusTerminalBodyClass} [data-voice-waveform] > div`, {
background: '#00D4FF !important' as any,
});
// light TDS
globalStyle(
`html[data-theme="light"] body.${lotusTerminalBodyClass} [data-voice-recorder="recording"]`,
{
background: 'rgba(0,98,184,0.05) !important' as any,
border: '1px solid rgba(0,98,184,0.22) !important' as any,
},
);
globalStyle(`html[data-theme="light"] body.${lotusTerminalBodyClass} [data-voice-rec-dot]`, {
background: '#006d35 !important' as any,
boxShadow: 'none',
});
globalStyle(`html[data-theme="light"] body.${lotusTerminalBodyClass} [data-voice-waveform] > div`, {
background: '#0062b8 !important' as any,
});
// ── Caption input TDS focus ring ──────────────────────────────────────────────
globalStyle(`body.${lotusTerminalBodyClass} [data-caption-input]:focus-visible`, {
borderColor: 'rgba(255,107,0,0.65) !important' as any,