PTT fixes, TDS expansions, performance hooks, state event renderers
PTT fixes (BUG-7/8/9): - BUG-7: Fix isEditable to use ownerDocument.body (works in EC iframe context) - BUG-8: Release mic if callEmbed changes during active PTT (cleanup fn) - BUG-9: Wire iframe blur/focus listeners for stuck-mic prevention PiP bug fix (BUG-11): - Track prevPipMode ref so position only resets when first entering pip mode, not on every callVisible change (user drag position preserved) GIF improvements (BUG-15): - Show user-visible error text in toolbar on GIF send failure - Also surface size-limit rejection with a 4-second auto-clearing message Performance: - useInterval: replace useMemo with useEffect for setInterval (React StrictMode safe) - usePan: add unmount cleanup effect to remove document mousemove/mouseup listeners Feature: timeline state event renderers (low effort, high value): - Added renderers for RoomEncryption, RoomJoinRules, RoomGuestAccess, RoomCanonicalAlias - These were silently falling through to the hidden-events fallback TDS (Lotus Terminal Design System): - Fix: correct 8 escaped template literals in GIF picker light-mode block - Add data-emoji-board attribute to EmojiBoardLayout for stable CSS targeting - Add Tooltip panel styles (dark + light mode) - Add Switch toggle styles (dark + light mode) - Add Spinner stroke colors (dark + light mode) - Add EmojiBoard panel styles (dark + light mode) - Add PopOut/Menu/floating panel styles (dark + light mode)
This commit is contained in:
@@ -241,6 +241,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
const { gifApiKey } = useClientConfig();
|
||||
const gifBtnRef = useRef<HTMLButtonElement>(null);
|
||||
const [hideStickerBtn, setHideStickerBtn] = useState(document.body.clientWidth < 500);
|
||||
const [gifError, setGifError] = React.useState<string | null>(null);
|
||||
|
||||
const isComposing = useComposingCheck();
|
||||
|
||||
@@ -469,7 +470,11 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
if (!contentType.startsWith('image/')) return;
|
||||
|
||||
const blob = await res.blob();
|
||||
if (blob.size > 20 * 1024 * 1024) return; // 20 MB cap
|
||||
if (blob.size > 20 * 1024 * 1024) {
|
||||
setGifError('GIF is too large (max 20 MB).');
|
||||
setTimeout(() => setGifError(null), 4000);
|
||||
return;
|
||||
}
|
||||
|
||||
const uploadRes = await mx.uploadContent(
|
||||
new File([blob], 'image.gif', { type: 'image/gif' }),
|
||||
@@ -485,6 +490,8 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('GIF send failed', e);
|
||||
setGifError('Failed to send GIF. Please try again.');
|
||||
setTimeout(() => setGifError(null), 4000);
|
||||
}
|
||||
},
|
||||
[mx, roomId]
|
||||
@@ -774,6 +781,11 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
)}
|
||||
</UseStateProvider>
|
||||
)}
|
||||
{gifError && (
|
||||
<Text size="T100" style={{ color: 'var(--tc-danger-normal)', padding: '2px 6px', alignSelf: 'center', whiteSpace: 'nowrap' }}>
|
||||
{gifError}
|
||||
</Text>
|
||||
)}
|
||||
<IconButton
|
||||
onClick={handleShareLocation}
|
||||
variant="SurfaceVariant"
|
||||
|
||||
Reference in New Issue
Block a user