fix: exponential backoff for 429 retries, cover thumbnails, 2 more modal dialogs

- matrix.ts: rateLimitedActions fallback delay now uses capped exponential
  backoff (min(1000 * 2^n, 30s)) instead of flat 3000ms when server omits
  Retry-After; server header still takes precedence
- RenderMessageContent: add objectFit:cover + 100% fill to video thumbnail
  <Image> so thumbnails fill their container without letterboxing (P5-6)
- CreateRoomModal, CreateSpaceModal: apply useModalStyle(480) for fullscreen
  on mobile
- LOTUS_BUGS: mark usePan memory leak + httpStatus check as FALSE POSITIVE;
  mark rateLimitedActions backoff as FIXED

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 15:32:17 -04:00
parent 8c711f5f4a
commit baa12823f7
5 changed files with 18 additions and 7 deletions
+7 -1
View File
@@ -232,7 +232,13 @@ export function RenderMessageContent({
<ThumbnailContent
info={info}
renderImage={(src) => (
<Image alt={body} title={body} src={src} loading="lazy" />
<Image
alt={body}
title={body}
src={src}
loading="lazy"
style={{ objectFit: 'cover', width: '100%', height: '100%' }}
/>
)}
/>
)
@@ -24,6 +24,7 @@ import {
import { CreateRoomModalState } from '../../state/createRoomModal';
import { stopPropagation } from '../../utils/keyboard';
import { CreateRoomType } from '../../components/create-room/types';
import { useModalStyle } from '../../hooks/useModalStyle';
type CreateRoomModalProps = {
state: CreateRoomModalState;
@@ -31,6 +32,7 @@ type CreateRoomModalProps = {
function CreateRoomModal({ state }: CreateRoomModalProps) {
const { spaceId, type } = state;
const closeDialog = useCloseCreateRoomModal();
const modalStyle = useModalStyle(480);
const allJoinedRooms = useAllJoinedRoomsSet();
const getRoom = useGetRoom(allJoinedRooms);
@@ -48,7 +50,7 @@ function CreateRoomModal({ state }: CreateRoomModalProps) {
escapeDeactivates: stopPropagation,
}}
>
<Modal size="300" flexHeight>
<Modal size="300" flexHeight style={modalStyle}>
<Box direction="Column">
<Header
size="500"
@@ -23,6 +23,7 @@ import {
} from '../../state/hooks/createSpaceModal';
import { CreateSpaceModalState } from '../../state/createSpaceModal';
import { stopPropagation } from '../../utils/keyboard';
import { useModalStyle } from '../../hooks/useModalStyle';
type CreateSpaceModalProps = {
state: CreateSpaceModalState;
@@ -30,6 +31,7 @@ type CreateSpaceModalProps = {
function CreateSpaceModal({ state }: CreateSpaceModalProps) {
const { spaceId } = state;
const closeDialog = useCloseCreateSpaceModal();
const modalStyle = useModalStyle(480);
const allJoinedRooms = useAllJoinedRoomsSet();
const getRoom = useGetRoom(allJoinedRooms);
@@ -47,7 +49,7 @@ function CreateSpaceModal({ state }: CreateSpaceModalProps) {
escapeDeactivates: stopPropagation,
}}
>
<Modal size="300" flexHeight>
<Modal size="300" flexHeight style={modalStyle}>
<Box direction="Column">
<Header
size="500"
+2 -1
View File
@@ -364,7 +364,8 @@ export const rateLimitedActions = async <T, R = void>(
return;
}
const waitMS = err.getRetryAfterMs() ?? 3000;
// Respect server Retry-After header; fall back to capped exponential backoff.
const waitMS = err.getRetryAfterMs() ?? Math.min(1000 * 2 ** retryCount, 30_000);
actionInterval = waitMS * 1.5;
await sleepForMs(waitMS);
retryCount += 1;