RoomListViewModel: Support primary filters in the view model (#29454)
* Track available filters and expose this info from the vm - Adds a separate hook that tracks the filtered rooms and the available filters. - When secondary filters are added, some of the primary filters will be selectively hidden. So track this info in the vm. * Write tests * Fix typescript error * Fix translation * Explain what a primary filter is
This commit is contained in:
@@ -14,16 +14,19 @@ import { LISTS_UPDATE_EVENT } from "../../../../../src/stores/room-list/SlidingR
|
||||
import { useRoomListViewModel } from "../../../../../src/components/viewmodels/roomlist/RoomListViewModel";
|
||||
import dispatcher from "../../../../../src/dispatcher/dispatcher";
|
||||
import { Action } from "../../../../../src/dispatcher/actions";
|
||||
import { FilterKey } from "../../../../../src/stores/room-list-v3/skip-list/filters";
|
||||
|
||||
describe("RoomListViewModel", () => {
|
||||
function mockAndCreateRooms() {
|
||||
const rooms = range(10).map((i) => mkStubRoom(`foo${i}:matrix.org`, `Foo ${i}`, undefined));
|
||||
jest.spyOn(RoomListStoreV3.instance, "getSortedRoomsInActiveSpace").mockImplementation(() => [...rooms]);
|
||||
return rooms;
|
||||
const fn = jest
|
||||
.spyOn(RoomListStoreV3.instance, "getSortedRoomsInActiveSpace")
|
||||
.mockImplementation(() => [...rooms]);
|
||||
return { rooms, fn };
|
||||
}
|
||||
|
||||
it("should return a list of rooms", async () => {
|
||||
const rooms = mockAndCreateRooms();
|
||||
const { rooms } = mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
|
||||
expect(vm.current.rooms).toHaveLength(10);
|
||||
@@ -33,7 +36,7 @@ describe("RoomListViewModel", () => {
|
||||
});
|
||||
|
||||
it("should update list of rooms on event from room list store", async () => {
|
||||
const rooms = mockAndCreateRooms();
|
||||
const { rooms } = mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
|
||||
const newRoom = mkStubRoom("bar:matrix.org", "Bar", undefined);
|
||||
@@ -46,7 +49,7 @@ describe("RoomListViewModel", () => {
|
||||
});
|
||||
|
||||
it("should dispatch view room action on openRoom", async () => {
|
||||
const rooms = mockAndCreateRooms();
|
||||
const { rooms } = mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
|
||||
const fn = jest.spyOn(dispatcher, "dispatch");
|
||||
@@ -59,4 +62,50 @@ describe("RoomListViewModel", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
describe("Filters", () => {
|
||||
it("should provide list of available filters", () => {
|
||||
mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
// should have 4 filters
|
||||
expect(vm.current.primaryFilters).toHaveLength(4);
|
||||
// check the order
|
||||
for (const [i, name] of ["Unread", "Favourites", "People", "Rooms"].entries()) {
|
||||
expect(vm.current.primaryFilters[i].name).toEqual(name);
|
||||
expect(vm.current.primaryFilters[i].active).toEqual(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("should get filtered rooms from RLS on toggle", () => {
|
||||
const { fn } = mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
// Let's say we toggle the People toggle
|
||||
const i = vm.current.primaryFilters.findIndex((f) => f.name === "People");
|
||||
act(() => {
|
||||
vm.current.primaryFilters[i].toggle();
|
||||
});
|
||||
expect(fn).toHaveBeenCalledWith([FilterKey.PeopleFilter]);
|
||||
expect(vm.current.primaryFilters[i].active).toEqual(true);
|
||||
});
|
||||
|
||||
it("should change active property on toggle", () => {
|
||||
mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
// Let's say we toggle the People filter
|
||||
const i = vm.current.primaryFilters.findIndex((f) => f.name === "People");
|
||||
expect(vm.current.primaryFilters[i].active).toEqual(false);
|
||||
act(() => {
|
||||
vm.current.primaryFilters[i].toggle();
|
||||
});
|
||||
expect(vm.current.primaryFilters[i].active).toEqual(true);
|
||||
|
||||
// Let's say that we toggle the Favourite filter
|
||||
const j = vm.current.primaryFilters.findIndex((f) => f.name === "Favourites");
|
||||
act(() => {
|
||||
vm.current.primaryFilters[j].toggle();
|
||||
});
|
||||
expect(vm.current.primaryFilters[i].active).toEqual(false);
|
||||
expect(vm.current.primaryFilters[j].active).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ describe("<RoomList />", () => {
|
||||
|
||||
matrixClient = stubClient();
|
||||
const rooms = Array.from({ length: 10 }, (_, i) => mkRoom(matrixClient, `room${i}`));
|
||||
vm = { rooms, openRoom: jest.fn() };
|
||||
vm = { rooms, openRoom: jest.fn(), primaryFilters: [] };
|
||||
|
||||
// Needed to render a room list cell
|
||||
DMRoomMap.makeShared(matrixClient);
|
||||
|
||||
Reference in New Issue
Block a user