feat: typing indicator orange dots, push-to-deafen hotkey, night light filter, message length counter

- #108: TypingIndicator reads lotusTerminal setting; applies var(--lt-accent-orange)
  to container so dots inherit via backgroundColor:currentColor
- #100: CallControls registers KeyM as push-to-deafen (e.code, e.repeat guard,
  ownerDocument.body iframe-safe editable check, [callEmbed] dep array)
- P5-5: nightLightEnabled/nightLightOpacity settings; position:fixed rgba(255,140,0)
  overlay inside JotaiProvider; Night Light tile + intensity slider (5–80%) in
  Settings → Appearance
- #101: RoomInput charCount state via Slate onChange + toPlainText; resets on
  room switch; displayed before send button when count > 0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 15:36:45 -04:00
parent 26f1e234a2
commit dedbd54199
6 changed files with 130 additions and 15 deletions
@@ -1,5 +1,7 @@
import React from 'react';
import { Box, as, toRem } from 'folds';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
import * as css from './TypingIndicator.css';
export type TypingIndicatorProps = {
@@ -8,18 +10,25 @@ export type TypingIndicatorProps = {
};
export const TypingIndicator = as<'div', TypingIndicatorProps>(
({ size, disableAnimation, style, ...props }, ref) => (
<Box
as="span"
alignItems="Center"
shrink="No"
style={{ gap: toRem(size === '300' ? 1 : 2), ...style }}
{...props}
ref={ref}
>
<span className={css.TypingDot({ size, index: '0', animated: !disableAnimation })} />
<span className={css.TypingDot({ size, index: '1', animated: !disableAnimation })} />
<span className={css.TypingDot({ size, index: '2', animated: !disableAnimation })} />
</Box>
),
function TypingIndicatorInner({ size, disableAnimation, style, ...props }, ref) {
const [lotusTerminal] = useSetting(settingsAtom, 'lotusTerminal');
return (
<Box
as="span"
alignItems="Center"
shrink="No"
style={{
gap: toRem(size === '300' ? 1 : 2),
color: lotusTerminal ? 'var(--lt-accent-orange)' : undefined,
...style,
}}
{...props}
ref={ref}
>
<span className={css.TypingDot({ size, index: '0', animated: !disableAnimation })} />
<span className={css.TypingDot({ size, index: '1', animated: !disableAnimation })} />
<span className={css.TypingDot({ size, index: '2', animated: !disableAnimation })} />
</Box>
);
},
);