diff --git a/src/components/viewmodels/roomlist/RoomListViewModel.tsx b/src/components/viewmodels/roomlist/RoomListViewModel.tsx
index 217eaefbd9..4b02c26647 100644
--- a/src/components/viewmodels/roomlist/RoomListViewModel.tsx
+++ b/src/components/viewmodels/roomlist/RoomListViewModel.tsx
@@ -21,6 +21,11 @@ import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
import { useStickyRoomList } from "./useStickyRoomList";
export interface RoomListViewState {
+ /**
+ * Whether the list of rooms is being loaded.
+ */
+ isLoadingRooms: boolean;
+
/**
* A list of rooms to be displayed in the left panel.
*/
@@ -98,6 +103,7 @@ export interface RoomListViewState {
export function useRoomListViewModel(): RoomListViewState {
const matrixClient = useMatrixClientContext();
const {
+ isLoadingRooms,
primaryFilters,
activePrimaryFilter,
rooms: filteredRooms,
@@ -120,6 +126,7 @@ export function useRoomListViewModel(): RoomListViewState {
const createRoom = useCallback(() => createRoomFunc(currentSpace), [currentSpace]);
return {
+ isLoadingRooms,
rooms,
canCreateRoom,
createRoom,
diff --git a/src/components/viewmodels/roomlist/useFilteredRooms.tsx b/src/components/viewmodels/roomlist/useFilteredRooms.tsx
index 4b4b9c0ec8..d8442a9d0b 100644
--- a/src/components/viewmodels/roomlist/useFilteredRooms.tsx
+++ b/src/components/viewmodels/roomlist/useFilteredRooms.tsx
@@ -35,6 +35,7 @@ export interface PrimaryFilter {
interface FilteredRooms {
primaryFilters: PrimaryFilter[];
+ isLoadingRooms: boolean;
rooms: Room[];
activateSecondaryFilter: (filter: SecondaryFilters) => void;
activeSecondaryFilter: SecondaryFilters;
@@ -115,6 +116,7 @@ export function useFilteredRooms(): FilteredRooms {
);
const [rooms, setRooms] = useState(() => RoomListStoreV3.instance.getSortedRoomsInActiveSpace());
+ const [isLoadingRooms, setIsLoadingRooms] = useState(true);
const updateRoomsFromStore = useCallback((filters: FilterKey[] = []): void => {
const newRooms = RoomListStoreV3.instance.getSortedRoomsInActiveSpace(filters);
@@ -135,6 +137,7 @@ export function useFilteredRooms(): FilteredRooms {
};
useEventEmitter(RoomListStoreV3.instance, LISTS_UPDATE_EVENT, () => {
+ setIsLoadingRooms(false);
const filters = getAppliedFilters();
updateRoomsFromStore(filters);
});
@@ -194,5 +197,12 @@ export function useFilteredRooms(): FilteredRooms {
const activePrimaryFilter = useMemo(() => primaryFilters.find((filter) => filter.active), [primaryFilters]);
- return { primaryFilters, activePrimaryFilter, rooms, activateSecondaryFilter, activeSecondaryFilter };
+ return {
+ isLoadingRooms,
+ primaryFilters,
+ activePrimaryFilter,
+ rooms,
+ activateSecondaryFilter,
+ activeSecondaryFilter,
+ };
}
diff --git a/src/components/views/rooms/RoomListPanel/RoomListView.tsx b/src/components/views/rooms/RoomListPanel/RoomListView.tsx
index f4800f7009..069b49adb8 100644
--- a/src/components/views/rooms/RoomListPanel/RoomListView.tsx
+++ b/src/components/views/rooms/RoomListPanel/RoomListView.tsx
@@ -11,6 +11,7 @@ import { useRoomListViewModel } from "../../../viewmodels/roomlist/RoomListViewM
import { RoomList } from "./RoomList";
import { EmptyRoomList } from "./EmptyRoomList";
import { RoomListPrimaryFilters } from "./RoomListPrimaryFilters";
+import Spinner from "../../elements/Spinner";
/**
* Host the room list and the (future) room filters
@@ -22,7 +23,7 @@ export function RoomListView(): JSX.Element {
return (
<>
- {isRoomListEmpty ? : }
+ {vm.isLoadingRooms ? : isRoomListEmpty ? : }
>
);
}
diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/EmptyRoomList-test.tsx b/test/unit-tests/components/views/rooms/RoomListPanel/EmptyRoomList-test.tsx
index b68929f74a..1483797778 100644
--- a/test/unit-tests/components/views/rooms/RoomListPanel/EmptyRoomList-test.tsx
+++ b/test/unit-tests/components/views/rooms/RoomListPanel/EmptyRoomList-test.tsx
@@ -20,6 +20,7 @@ describe("", () => {
beforeEach(() => {
vm = {
+ isLoadingRooms: false,
rooms: [],
primaryFilters: [],
activateSecondaryFilter: jest.fn().mockReturnValue({}),
diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/RoomList-test.tsx b/test/unit-tests/components/views/rooms/RoomListPanel/RoomList-test.tsx
index 0d837c3a20..d72a78d36a 100644
--- a/test/unit-tests/components/views/rooms/RoomListPanel/RoomList-test.tsx
+++ b/test/unit-tests/components/views/rooms/RoomListPanel/RoomList-test.tsx
@@ -29,6 +29,7 @@ describe("", () => {
matrixClient = stubClient();
const rooms = Array.from({ length: 10 }, (_, i) => mkRoom(matrixClient, `room${i}`));
vm = {
+ isLoadingRooms: false,
rooms,
primaryFilters: [],
activateSecondaryFilter: () => {},
diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx
index 79bfbb6dc0..4a80ea068e 100644
--- a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx
+++ b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx
@@ -20,6 +20,7 @@ describe("", () => {
beforeEach(() => {
vm = {
+ isLoadingRooms: false,
rooms: [],
canCreateRoom: true,
createRoom: jest.fn(),
diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListView-test.tsx b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListView-test.tsx
index f56d30976a..e66e430e18 100644
--- a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListView-test.tsx
+++ b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListView-test.tsx
@@ -24,6 +24,7 @@ jest.mock("../../../../../../src/components/viewmodels/roomlist/RoomListViewMode
describe("", () => {
const defaultValue: RoomListViewState = {
+ isLoadingRooms: false,
rooms: [],
primaryFilters: [],
activateSecondaryFilter: jest.fn().mockReturnValue({}),