{
+ {audioFeedArraysForCalls}
);
}
diff --git a/src/components/structures/SpaceRoomDirectory.tsx b/src/components/structures/SpaceRoomDirectory.tsx
index 8d6c9f0a70..db7fd13753 100644
--- a/src/components/structures/SpaceRoomDirectory.tsx
+++ b/src/components/structures/SpaceRoomDirectory.tsx
@@ -39,6 +39,7 @@ import {mediaFromMxc} from "../../customisations/Media";
import InfoTooltip from "../views/elements/InfoTooltip";
import TextWithTooltip from "../views/elements/TextWithTooltip";
import {useStateToggle} from "../../hooks/useStateToggle";
+import {getOrder} from "../../stores/SpaceStore";
interface IHierarchyProps {
space: Room;
@@ -254,7 +255,11 @@ export const HierarchyLevel = ({
const space = cli.getRoom(spaceId);
const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
- const sortedChildren = sortBy([...(relations.get(spaceId)?.values() || [])], ev => ev.content.order || null);
+ const children = Array.from(relations.get(spaceId)?.values() || []);
+ const sortedChildren = sortBy(children, ev => {
+ // XXX: Space Summary API doesn't give the child origin_server_ts but once it does we should use it for sorting
+ return getOrder(ev.content.order, null, ev.state_key);
+ });
const [subspaces, childRooms] = sortedChildren.reduce((result, ev: ISpaceSummaryEvent) => {
const roomId = ev.state_key;
if (!rooms.has(roomId)) return result;
diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx
index cdf9dc02d3..a7a95d711c 100644
--- a/src/components/structures/SpaceRoomView.tsx
+++ b/src/components/structures/SpaceRoomView.tsx
@@ -52,7 +52,7 @@ import {useStateToggle} from "../../hooks/useStateToggle";
import SpaceStore from "../../stores/SpaceStore";
import FacePile from "../views/elements/FacePile";
import {AddExistingToSpace} from "../views/dialogs/AddExistingToSpaceDialog";
-import {allSettled} from "../../utils/promise";
+import {sleep} from "../../utils/promise";
import {calculateRoomVia} from "../../utils/permalinks/Permalinks";
interface IProps {
@@ -389,15 +389,24 @@ const SpaceAddExistingRooms = ({ space, onFinished }) => {
let buttonLabel = _t("Skip for now");
if (selectedToAdd.size > 0) {
onClick = async () => {
- // TODO rate limiting
setBusy(true);
- try {
- await allSettled(Array.from(selectedToAdd).map((room) =>
- SpaceStore.instance.addRoomToSpace(space, room.roomId, calculateRoomVia(room))));
- onFinished(true);
- } catch (e) {
- console.error("Failed to add rooms to space", e);
- setError(_t("Failed to add rooms to space"));
+
+ for (const room of selectedToAdd) {
+ const via = calculateRoomVia(room);
+ try {
+ await SpaceStore.instance.addRoomToSpace(space, room.roomId, via).catch(async e => {
+ if (e.errcode === "M_LIMIT_EXCEEDED") {
+ await sleep(e.data.retry_after_ms);
+ return SpaceStore.instance.addRoomToSpace(space, room.roomId, via); // retry
+ }
+
+ throw e;
+ });
+ } catch (e) {
+ console.error("Failed to add rooms to space", e);
+ setError(_t("Failed to add rooms to space"));
+ break;
+ }
}
setBusy(false);
};
diff --git a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
index 1f45a76008..a33248200c 100644
--- a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
+++ b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import React, {useContext, useState} from "react";
+import React, {useContext, useMemo, useState} from "react";
import classNames from "classnames";
import {Room} from "matrix-js-sdk/src/models/room";
import {MatrixClient} from "matrix-js-sdk/src/client";
@@ -29,11 +29,13 @@ import RoomAvatar from "../avatars/RoomAvatar";
import {getDisplayAliasForRoom} from "../../../Rooms";
import AccessibleButton from "../elements/AccessibleButton";
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
-import {allSettled} from "../../../utils/promise";
+import {sleep} from "../../../utils/promise";
import DMRoomMap from "../../../utils/DMRoomMap";
import {calculateRoomVia} from "../../../utils/permalinks/Permalinks";
import StyledCheckbox from "../elements/StyledCheckbox";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
+import {sortRooms} from "../../../stores/room-list/algorithms/tag-sorting/RecentAlgorithm";
+import ProgressBar from "../elements/ProgressBar";
interface IProps extends IDialogProps {
matrixClient: MatrixClient;
@@ -45,7 +47,11 @@ const Entry = ({ room, checked, onChange }) => {
return ;
};
@@ -57,6 +63,8 @@ interface IAddExistingToSpaceProps {
export const AddExistingToSpace: React.FC = ({ space, selected, onChange }) => {
const cli = useContext(MatrixClientContext);
+ const visibleRooms = useMemo(() => sortRooms(cli.getVisibleRooms()), [cli]);
+
const [query, setQuery] = useState("");
const lcQuery = query.toLowerCase();
@@ -65,7 +73,7 @@ export const AddExistingToSpace: React.FC = ({ space,
const existingRoomsSet = new Set(SpaceStore.instance.getChildRooms(space.roomId));
const joinRule = space.getJoinRule();
- const [spaces, rooms, dms] = cli.getVisibleRooms().reduce((arr, room) => {
+ const [spaces, rooms, dms] = visibleRooms.reduce((arr, room) => {
if (room.getMyMembership() !== "join") return arr;
if (!room.name.toLowerCase().includes(lcQuery)) return arr;
@@ -101,9 +109,9 @@ export const AddExistingToSpace: React.FC = ({ space,
key={room.roomId}
room={room}
checked={selected.has(room)}
- onChange={(checked) => {
+ onChange={onChange ? (checked) => {
onChange(checked, room);
- }}
+ } : null}
/>;
}) }
@@ -117,9 +125,9 @@ export const AddExistingToSpace: React.FC = ({ space,
key={space.roomId}
room={space}
checked={selected.has(space)}
- onChange={(checked) => {
+ onChange={onChange ? (checked) => {
onChange(checked, space);
- }}
+ } : null}
/>;
}) }