mirror of
https://github.com/RGBCube/cinny
synced 2025-07-30 00:17:45 +00:00
Fix rate limit when reordering in space lobby (#2254)
* move can drop lobby item logic to hook * add comment * resolve rate limit when reordering space children
This commit is contained in:
parent
83057ebbd4
commit
a23279e633
4 changed files with 270 additions and 187 deletions
|
@ -1,5 +1,5 @@
|
|||
import React, { MouseEventHandler, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { Box, Icon, IconButton, Icons, Line, Scroll, config } from 'folds';
|
||||
import { Box, Chip, Icon, IconButton, Icons, Line, Scroll, Spinner, Text, config } from 'folds';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
@ -36,7 +36,7 @@ import { makeLobbyCategoryId } from '../../state/closedLobbyCategories';
|
|||
import { useCategoryHandler } from '../../hooks/useCategoryHandler';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { allRoomsAtom } from '../../state/room-list/roomList';
|
||||
import { getCanonicalAliasOrRoomId } from '../../utils/matrix';
|
||||
import { getCanonicalAliasOrRoomId, rateLimitedActions } from '../../utils/matrix';
|
||||
import { getSpaceRoomPath } from '../../pages/pathUtils';
|
||||
import { StateEvent } from '../../../types/matrix/room';
|
||||
import { CanDropCallback, useDnDMonitor } from './DnD';
|
||||
|
@ -53,6 +53,95 @@ import { roomToParentsAtom } from '../../state/room/roomToParents';
|
|||
import { AccountDataEvent } from '../../../types/matrix/accountData';
|
||||
import { useRoomMembers } from '../../hooks/useRoomMembers';
|
||||
import { SpaceHierarchy } from './SpaceHierarchy';
|
||||
import { useGetRoom } from '../../hooks/useGetRoom';
|
||||
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
|
||||
|
||||
const useCanDropLobbyItem = (
|
||||
space: Room,
|
||||
roomsPowerLevels: Map<string, IPowerLevels>,
|
||||
getRoom: (roomId: string) => Room | undefined,
|
||||
canEditSpaceChild: (powerLevels: IPowerLevels) => boolean
|
||||
): CanDropCallback => {
|
||||
const mx = useMatrixClient();
|
||||
|
||||
const canDropSpace: CanDropCallback = useCallback(
|
||||
(item, container) => {
|
||||
if (!('space' in container.item)) {
|
||||
// can not drop around rooms.
|
||||
// space can only be drop around other spaces
|
||||
return false;
|
||||
}
|
||||
|
||||
const containerSpaceId = space.roomId;
|
||||
|
||||
if (
|
||||
getRoom(containerSpaceId) === undefined ||
|
||||
!canEditSpaceChild(roomsPowerLevels.get(containerSpaceId) ?? {})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
[space, roomsPowerLevels, getRoom, canEditSpaceChild]
|
||||
);
|
||||
|
||||
const canDropRoom: CanDropCallback = useCallback(
|
||||
(item, container) => {
|
||||
const containerSpaceId =
|
||||
'space' in container.item ? container.item.roomId : container.item.parentId;
|
||||
|
||||
const draggingOutsideSpace = item.parentId !== containerSpaceId;
|
||||
const restrictedItem = mx.getRoom(item.roomId)?.getJoinRule() === JoinRule.Restricted;
|
||||
|
||||
// check and do not allow restricted room to be dragged outside
|
||||
// current space if can't change `m.room.join_rules` `content.allow`
|
||||
if (draggingOutsideSpace && restrictedItem) {
|
||||
const itemPowerLevel = roomsPowerLevels.get(item.roomId) ?? {};
|
||||
const userPLInItem = powerLevelAPI.getPowerLevel(
|
||||
itemPowerLevel,
|
||||
mx.getUserId() ?? undefined
|
||||
);
|
||||
const canChangeJoinRuleAllow = powerLevelAPI.canSendStateEvent(
|
||||
itemPowerLevel,
|
||||
StateEvent.RoomJoinRules,
|
||||
userPLInItem
|
||||
);
|
||||
if (!canChangeJoinRuleAllow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
getRoom(containerSpaceId) === undefined ||
|
||||
!canEditSpaceChild(roomsPowerLevels.get(containerSpaceId) ?? {})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[mx, getRoom, canEditSpaceChild, roomsPowerLevels]
|
||||
);
|
||||
|
||||
const canDrop: CanDropCallback = useCallback(
|
||||
(item, container): boolean => {
|
||||
if (item.roomId === container.item.roomId || item.roomId === container.nextRoomId) {
|
||||
// can not drop before or after itself
|
||||
return false;
|
||||
}
|
||||
|
||||
// if we are dragging a space
|
||||
if ('space' in item) {
|
||||
return canDropSpace(item, container);
|
||||
}
|
||||
|
||||
return canDropRoom(item, container);
|
||||
},
|
||||
[canDropSpace, canDropRoom]
|
||||
);
|
||||
|
||||
return canDrop;
|
||||
};
|
||||
|
||||
export function Lobby() {
|
||||
const navigate = useNavigate();
|
||||
|
@ -92,15 +181,7 @@ export function Lobby() {
|
|||
useCallback((w, height) => setHeroSectionHeight(height), [])
|
||||
);
|
||||
|
||||
const getRoom = useCallback(
|
||||
(rId: string) => {
|
||||
if (allJoinedRooms.has(rId)) {
|
||||
return mx.getRoom(rId) ?? undefined;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
[mx, allJoinedRooms]
|
||||
);
|
||||
const getRoom = useGetRoom(allJoinedRooms);
|
||||
|
||||
const canEditSpaceChild = useCallback(
|
||||
(powerLevels: IPowerLevels) =>
|
||||
|
@ -150,180 +231,155 @@ export function Lobby() {
|
|||
)
|
||||
);
|
||||
|
||||
const canDrop: CanDropCallback = useCallback(
|
||||
(item, container): boolean => {
|
||||
const restrictedItem = mx.getRoom(item.roomId)?.getJoinRule() === JoinRule.Restricted;
|
||||
if (item.roomId === container.item.roomId || item.roomId === container.nextRoomId) {
|
||||
// can not drop before or after itself
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('space' in item) {
|
||||
if (!('space' in container.item)) return false;
|
||||
const containerSpaceId = space.roomId;
|
||||
|
||||
if (
|
||||
getRoom(containerSpaceId) === undefined ||
|
||||
!canEditSpaceChild(roomsPowerLevels.get(containerSpaceId) ?? {})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const containerSpaceId =
|
||||
'space' in container.item ? container.item.roomId : container.item.parentId;
|
||||
|
||||
const dropOutsideSpace = item.parentId !== containerSpaceId;
|
||||
|
||||
if (dropOutsideSpace && restrictedItem) {
|
||||
// do not allow restricted room to drop outside
|
||||
// current space if can't change join rule allow
|
||||
const itemPowerLevel = roomsPowerLevels.get(item.roomId) ?? {};
|
||||
const userPLInItem = powerLevelAPI.getPowerLevel(
|
||||
itemPowerLevel,
|
||||
mx.getUserId() ?? undefined
|
||||
);
|
||||
const canChangeJoinRuleAllow = powerLevelAPI.canSendStateEvent(
|
||||
itemPowerLevel,
|
||||
StateEvent.RoomJoinRules,
|
||||
userPLInItem
|
||||
);
|
||||
if (!canChangeJoinRuleAllow) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
getRoom(containerSpaceId) === undefined ||
|
||||
!canEditSpaceChild(roomsPowerLevels.get(containerSpaceId) ?? {})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[getRoom, space.roomId, roomsPowerLevels, canEditSpaceChild, mx]
|
||||
const canDrop: CanDropCallback = useCanDropLobbyItem(
|
||||
space,
|
||||
roomsPowerLevels,
|
||||
getRoom,
|
||||
canEditSpaceChild
|
||||
);
|
||||
|
||||
const reorderSpace = useCallback(
|
||||
(item: HierarchyItemSpace, containerItem: HierarchyItem) => {
|
||||
if (!item.parentId) return;
|
||||
const [reorderSpaceState, reorderSpace] = useAsyncCallback(
|
||||
useCallback(
|
||||
async (item: HierarchyItemSpace, containerItem: HierarchyItem) => {
|
||||
if (!item.parentId) return;
|
||||
|
||||
const itemSpaces: HierarchyItemSpace[] = hierarchy
|
||||
.map((i) => i.space)
|
||||
.filter((i) => i.roomId !== item.roomId);
|
||||
const itemSpaces: HierarchyItemSpace[] = hierarchy
|
||||
.map((i) => i.space)
|
||||
.filter((i) => i.roomId !== item.roomId);
|
||||
|
||||
const beforeIndex = itemSpaces.findIndex((i) => i.roomId === containerItem.roomId);
|
||||
const insertIndex = beforeIndex + 1;
|
||||
const beforeIndex = itemSpaces.findIndex((i) => i.roomId === containerItem.roomId);
|
||||
const insertIndex = beforeIndex + 1;
|
||||
|
||||
itemSpaces.splice(insertIndex, 0, {
|
||||
...item,
|
||||
content: { ...item.content, order: undefined },
|
||||
});
|
||||
itemSpaces.splice(insertIndex, 0, {
|
||||
...item,
|
||||
content: { ...item.content, order: undefined },
|
||||
});
|
||||
|
||||
const currentOrders = itemSpaces.map((i) => {
|
||||
if (typeof i.content.order === 'string' && lex.has(i.content.order)) {
|
||||
return i.content.order;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
const currentOrders = itemSpaces.map((i) => {
|
||||
if (typeof i.content.order === 'string' && lex.has(i.content.order)) {
|
||||
return i.content.order;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const newOrders = orderKeys(lex, currentOrders);
|
||||
const newOrders = orderKeys(lex, currentOrders);
|
||||
|
||||
newOrders?.forEach((orderKey, index) => {
|
||||
const itm = itemSpaces[index];
|
||||
if (!itm || !itm.parentId) return;
|
||||
const parentPL = roomsPowerLevels.get(itm.parentId);
|
||||
const canEdit = parentPL && canEditSpaceChild(parentPL);
|
||||
if (canEdit && orderKey !== currentOrders[index]) {
|
||||
mx.sendStateEvent(
|
||||
itm.parentId,
|
||||
StateEvent.SpaceChild as any,
|
||||
{ ...itm.content, order: orderKey },
|
||||
itm.roomId
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
[mx, hierarchy, lex, roomsPowerLevels, canEditSpaceChild]
|
||||
);
|
||||
const reorders = newOrders
|
||||
?.map((orderKey, index) => ({
|
||||
item: itemSpaces[index],
|
||||
orderKey,
|
||||
}))
|
||||
.filter((reorder, index) => {
|
||||
if (!reorder.item.parentId) return false;
|
||||
const parentPL = roomsPowerLevels.get(reorder.item.parentId);
|
||||
const canEdit = parentPL && canEditSpaceChild(parentPL);
|
||||
return canEdit && reorder.orderKey !== currentOrders[index];
|
||||
});
|
||||
|
||||
const reorderRoom = useCallback(
|
||||
(item: HierarchyItem, containerItem: HierarchyItem): void => {
|
||||
const itemRoom = mx.getRoom(item.roomId);
|
||||
if (!item.parentId) {
|
||||
return;
|
||||
}
|
||||
const containerParentId: string =
|
||||
'space' in containerItem ? containerItem.roomId : containerItem.parentId;
|
||||
const itemContent = item.content;
|
||||
|
||||
if (item.parentId !== containerParentId) {
|
||||
mx.sendStateEvent(item.parentId, StateEvent.SpaceChild as any, {}, item.roomId);
|
||||
}
|
||||
|
||||
if (
|
||||
itemRoom &&
|
||||
itemRoom.getJoinRule() === JoinRule.Restricted &&
|
||||
item.parentId !== containerParentId
|
||||
) {
|
||||
// change join rule allow parameter when dragging
|
||||
// restricted room from one space to another
|
||||
const joinRuleContent = getStateEvent(
|
||||
itemRoom,
|
||||
StateEvent.RoomJoinRules
|
||||
)?.getContent<RoomJoinRulesEventContent>();
|
||||
|
||||
if (joinRuleContent) {
|
||||
const allow =
|
||||
joinRuleContent.allow?.filter((allowRule) => allowRule.room_id !== item.parentId) ?? [];
|
||||
allow.push({ type: RestrictedAllowType.RoomMembership, room_id: containerParentId });
|
||||
mx.sendStateEvent(itemRoom.roomId, StateEvent.RoomJoinRules as any, {
|
||||
...joinRuleContent,
|
||||
allow,
|
||||
if (reorders) {
|
||||
await rateLimitedActions(reorders, async (reorder) => {
|
||||
if (!reorder.item.parentId) return;
|
||||
await mx.sendStateEvent(
|
||||
reorder.item.parentId,
|
||||
StateEvent.SpaceChild as any,
|
||||
{ ...reorder.item.content, order: reorder.orderKey },
|
||||
reorder.item.roomId
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const itemSpaces = Array.from(
|
||||
hierarchy?.find((i) => i.space.roomId === containerParentId)?.rooms ?? []
|
||||
);
|
||||
|
||||
const beforeItem: HierarchyItem | undefined =
|
||||
'space' in containerItem ? undefined : containerItem;
|
||||
const beforeIndex = itemSpaces.findIndex((i) => i.roomId === beforeItem?.roomId);
|
||||
const insertIndex = beforeIndex + 1;
|
||||
|
||||
itemSpaces.splice(insertIndex, 0, {
|
||||
...item,
|
||||
parentId: containerParentId,
|
||||
content: { ...itemContent, order: undefined },
|
||||
});
|
||||
|
||||
const currentOrders = itemSpaces.map((i) => {
|
||||
if (typeof i.content.order === 'string' && lex.has(i.content.order)) {
|
||||
return i.content.order;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const newOrders = orderKeys(lex, currentOrders);
|
||||
|
||||
newOrders?.forEach((orderKey, index) => {
|
||||
const itm = itemSpaces[index];
|
||||
if (itm && orderKey !== currentOrders[index]) {
|
||||
mx.sendStateEvent(
|
||||
containerParentId,
|
||||
StateEvent.SpaceChild as any,
|
||||
{ ...itm.content, order: orderKey },
|
||||
itm.roomId
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
[mx, hierarchy, lex]
|
||||
},
|
||||
[mx, hierarchy, lex, roomsPowerLevels, canEditSpaceChild]
|
||||
)
|
||||
);
|
||||
const reorderingSpace = reorderSpaceState.status === AsyncStatus.Loading;
|
||||
|
||||
const [reorderRoomState, reorderRoom] = useAsyncCallback(
|
||||
useCallback(
|
||||
async (item: HierarchyItem, containerItem: HierarchyItem) => {
|
||||
const itemRoom = mx.getRoom(item.roomId);
|
||||
if (!item.parentId) {
|
||||
return;
|
||||
}
|
||||
const containerParentId: string =
|
||||
'space' in containerItem ? containerItem.roomId : containerItem.parentId;
|
||||
const itemContent = item.content;
|
||||
|
||||
// remove from current space
|
||||
if (item.parentId !== containerParentId) {
|
||||
mx.sendStateEvent(item.parentId, StateEvent.SpaceChild as any, {}, item.roomId);
|
||||
}
|
||||
|
||||
if (
|
||||
itemRoom &&
|
||||
itemRoom.getJoinRule() === JoinRule.Restricted &&
|
||||
item.parentId !== containerParentId
|
||||
) {
|
||||
// change join rule allow parameter when dragging
|
||||
// restricted room from one space to another
|
||||
const joinRuleContent = getStateEvent(
|
||||
itemRoom,
|
||||
StateEvent.RoomJoinRules
|
||||
)?.getContent<RoomJoinRulesEventContent>();
|
||||
|
||||
if (joinRuleContent) {
|
||||
const allow =
|
||||
joinRuleContent.allow?.filter((allowRule) => allowRule.room_id !== item.parentId) ??
|
||||
[];
|
||||
allow.push({ type: RestrictedAllowType.RoomMembership, room_id: containerParentId });
|
||||
mx.sendStateEvent(itemRoom.roomId, StateEvent.RoomJoinRules as any, {
|
||||
...joinRuleContent,
|
||||
allow,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const itemSpaces = Array.from(
|
||||
hierarchy?.find((i) => i.space.roomId === containerParentId)?.rooms ?? []
|
||||
);
|
||||
|
||||
const beforeItem: HierarchyItem | undefined =
|
||||
'space' in containerItem ? undefined : containerItem;
|
||||
const beforeIndex = itemSpaces.findIndex((i) => i.roomId === beforeItem?.roomId);
|
||||
const insertIndex = beforeIndex + 1;
|
||||
|
||||
itemSpaces.splice(insertIndex, 0, {
|
||||
...item,
|
||||
parentId: containerParentId,
|
||||
content: { ...itemContent, order: undefined },
|
||||
});
|
||||
|
||||
const currentOrders = itemSpaces.map((i) => {
|
||||
if (typeof i.content.order === 'string' && lex.has(i.content.order)) {
|
||||
return i.content.order;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const newOrders = orderKeys(lex, currentOrders);
|
||||
|
||||
const reorders = newOrders
|
||||
?.map((orderKey, index) => ({
|
||||
item: itemSpaces[index],
|
||||
orderKey,
|
||||
}))
|
||||
.filter((reorder, index) => reorder.item && reorder.orderKey !== currentOrders[index]);
|
||||
|
||||
if (reorders) {
|
||||
await rateLimitedActions(reorders, async (reorder) => {
|
||||
await mx.sendStateEvent(
|
||||
containerParentId,
|
||||
StateEvent.SpaceChild as any,
|
||||
{ ...reorder.item.content, order: reorder.orderKey },
|
||||
reorder.item.roomId
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
[mx, hierarchy, lex]
|
||||
)
|
||||
);
|
||||
const reorderingRoom = reorderRoomState.status === AsyncStatus.Loading;
|
||||
const reordering = reorderingRoom || reorderingSpace;
|
||||
|
||||
useDnDMonitor(
|
||||
scrollRef,
|
||||
|
@ -449,6 +505,7 @@ export function Lobby() {
|
|||
draggingItem={draggingItem}
|
||||
onDragging={setDraggingItem}
|
||||
canDrop={canDrop}
|
||||
disabledReorder={reordering}
|
||||
nextSpaceId={nextSpaceId}
|
||||
getRoom={getRoom}
|
||||
pinned={sidebarSpaces.has(item.space.roomId)}
|
||||
|
@ -460,6 +517,28 @@ export function Lobby() {
|
|||
);
|
||||
})}
|
||||
</div>
|
||||
{reordering && (
|
||||
<Box
|
||||
style={{
|
||||
position: 'absolute',
|
||||
bottom: config.space.S400,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 2,
|
||||
pointerEvents: 'none',
|
||||
}}
|
||||
justifyContent="Center"
|
||||
>
|
||||
<Chip
|
||||
variant="Secondary"
|
||||
outlined
|
||||
radii="Pill"
|
||||
before={<Spinner variant="Secondary" fill="Soft" size="100" />}
|
||||
>
|
||||
<Text size="L400">Reordering</Text>
|
||||
</Chip>
|
||||
</Box>
|
||||
)}
|
||||
</PageContentCenter>
|
||||
</PageContent>
|
||||
</Scroll>
|
||||
|
|
|
@ -31,6 +31,7 @@ type SpaceHierarchyProps = {
|
|||
draggingItem?: HierarchyItem;
|
||||
onDragging: (item?: HierarchyItem) => void;
|
||||
canDrop: CanDropCallback;
|
||||
disabledReorder?: boolean;
|
||||
nextSpaceId?: string;
|
||||
getRoom: (roomId: string) => Room | undefined;
|
||||
pinned: boolean;
|
||||
|
@ -54,6 +55,7 @@ export const SpaceHierarchy = forwardRef<HTMLDivElement, SpaceHierarchyProps>(
|
|||
draggingItem,
|
||||
onDragging,
|
||||
canDrop,
|
||||
disabledReorder,
|
||||
nextSpaceId,
|
||||
getRoom,
|
||||
pinned,
|
||||
|
@ -116,7 +118,9 @@ export const SpaceHierarchy = forwardRef<HTMLDivElement, SpaceHierarchyProps>(
|
|||
handleClose={handleClose}
|
||||
getRoom={getRoom}
|
||||
canEditChild={canEditSpaceChild(spacePowerLevels)}
|
||||
canReorder={parentPowerLevels ? canEditSpaceChild(parentPowerLevels) : false}
|
||||
canReorder={
|
||||
parentPowerLevels && !disabledReorder ? canEditSpaceChild(parentPowerLevels) : false
|
||||
}
|
||||
options={
|
||||
parentId &&
|
||||
parentPowerLevels && (
|
||||
|
@ -174,7 +178,7 @@ export const SpaceHierarchy = forwardRef<HTMLDivElement, SpaceHierarchyProps>(
|
|||
dm={mDirects.has(roomItem.roomId)}
|
||||
onOpen={onOpenRoom}
|
||||
getRoom={getRoom}
|
||||
canReorder={canEditSpaceChild(spacePowerLevels)}
|
||||
canReorder={canEditSpaceChild(spacePowerLevels) && !disabledReorder}
|
||||
options={
|
||||
<HierarchyItemMenu
|
||||
item={roomItem}
|
||||
|
|
|
@ -28,9 +28,11 @@ import { allRoomsAtom } from '../../state/room-list/roomList';
|
|||
import { mDirectAtom } from '../../state/mDirectList';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { getViaServers } from '../../plugins/via-servers';
|
||||
import { rateLimitedActions } from '../../utils/matrix';
|
||||
import { useAlive } from '../../hooks/useAlive';
|
||||
|
||||
function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) {
|
||||
const mountStore = useStore(roomId);
|
||||
const alive = useAlive();
|
||||
const [debounce] = useState(new Debounce());
|
||||
const [process, setProcess] = useState(null);
|
||||
const [allRoomIds, setAllRoomIds] = useState([]);
|
||||
|
@ -68,14 +70,14 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) {
|
|||
const handleAdd = async () => {
|
||||
setProcess(`Adding ${selected.length} items...`);
|
||||
|
||||
const promises = selected.map((rId) => {
|
||||
await rateLimitedActions(selected, async (rId) => {
|
||||
const room = mx.getRoom(rId);
|
||||
const via = getViaServers(room);
|
||||
if (via.length === 0) {
|
||||
via.push(getIdServer(rId));
|
||||
}
|
||||
|
||||
return mx.sendStateEvent(
|
||||
await mx.sendStateEvent(
|
||||
roomId,
|
||||
'm.space.child',
|
||||
{
|
||||
|
@ -87,9 +89,7 @@ function SpaceAddExistingContent({ roomId, spaces: onlySpaces }) {
|
|||
);
|
||||
});
|
||||
|
||||
mountStore.setItem(true);
|
||||
await Promise.allSettled(promises);
|
||||
if (mountStore.getItem() !== true) return;
|
||||
if (!alive()) return;
|
||||
|
||||
const roomIds = onlySpaces ? [...spaces] : [...rooms, ...directs];
|
||||
const allIds = roomIds.filter(
|
||||
|
|
|
@ -300,7 +300,7 @@ export const downloadEncryptedMedia = async (
|
|||
|
||||
export const rateLimitedActions = async <T, R = void>(
|
||||
data: T[],
|
||||
callback: (item: T) => Promise<R>,
|
||||
callback: (item: T, index: number) => Promise<R>,
|
||||
maxRetryCount?: number
|
||||
) => {
|
||||
let retryCount = 0;
|
||||
|
@ -312,8 +312,8 @@ export const rateLimitedActions = async <T, R = void>(
|
|||
setTimeout(resolve, ms);
|
||||
});
|
||||
|
||||
const performAction = async (dataItem: T) => {
|
||||
const [err] = await to<R, MatrixError>(callback(dataItem));
|
||||
const performAction = async (dataItem: T, index: number) => {
|
||||
const [err] = await to<R, MatrixError>(callback(dataItem, index));
|
||||
|
||||
if (err?.httpStatus === 429) {
|
||||
if (retryCount === maxRetryCount) {
|
||||
|
@ -321,11 +321,11 @@ export const rateLimitedActions = async <T, R = void>(
|
|||
}
|
||||
|
||||
const waitMS = err.getRetryAfterMs() ?? 3000;
|
||||
actionInterval = waitMS + 500;
|
||||
actionInterval = waitMS * 1.5;
|
||||
await sleepForMs(waitMS);
|
||||
retryCount += 1;
|
||||
|
||||
await performAction(dataItem);
|
||||
await performAction(dataItem, index);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -333,7 +333,7 @@ export const rateLimitedActions = async <T, R = void>(
|
|||
const dataItem = data[i];
|
||||
retryCount = 0;
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await performAction(dataItem);
|
||||
await performAction(dataItem, i);
|
||||
if (actionInterval > 0) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await sleepForMs(actionInterval);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue