RoomListViewModel: Add functionality to toggle message preview setting (#29511)
* Add setting for showing message previews * Add hook to track and toggle message preview * Use hook in view model * Add tests * Fix tests * Fix lint * Fix typo
This commit is contained in:
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import type { Room } from "matrix-js-sdk/src/matrix";
|
||||
import { type PrimaryFilter, type SecondaryFilters, useFilteredRooms } from "./useFilteredRooms";
|
||||
import { type SortOption, useSorter } from "./useSorter";
|
||||
import { useMessagePreviewToggle } from "./useMessagePreviewToggle";
|
||||
|
||||
export interface RoomListViewState {
|
||||
/**
|
||||
@@ -39,6 +40,16 @@ export interface RoomListViewState {
|
||||
* The currently active sort option.
|
||||
*/
|
||||
activeSortOption: SortOption;
|
||||
|
||||
/**
|
||||
* Whether message previews must be shown or not.
|
||||
*/
|
||||
shouldShowMessagePreview: boolean;
|
||||
|
||||
/**
|
||||
* A function to turn on/off message previews.
|
||||
*/
|
||||
toggleMessagePreview: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,6 +59,7 @@ export interface RoomListViewState {
|
||||
export function useRoomListViewModel(): RoomListViewState {
|
||||
const { primaryFilters, rooms, activateSecondaryFilter, activeSecondaryFilter } = useFilteredRooms();
|
||||
const { activeSortOption, sort } = useSorter();
|
||||
const { shouldShowMessagePreview, toggleMessagePreview } = useMessagePreviewToggle();
|
||||
|
||||
return {
|
||||
rooms,
|
||||
@@ -56,5 +68,7 @@ export function useRoomListViewModel(): RoomListViewState {
|
||||
activeSecondaryFilter,
|
||||
activeSortOption,
|
||||
sort,
|
||||
shouldShowMessagePreview,
|
||||
toggleMessagePreview,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
|
||||
interface MessagePreviewToggleState {
|
||||
shouldShowMessagePreview: boolean;
|
||||
toggleMessagePreview: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* This hook:
|
||||
* - Provides a state that tracks whether message previews are turned on or off.
|
||||
* - Provides a function to toggle message previews.
|
||||
*/
|
||||
export function useMessagePreviewToggle(): MessagePreviewToggleState {
|
||||
const [shouldShowMessagePreview, setShouldShowMessagePreview] = useState(() =>
|
||||
SettingsStore.getValue("RoomList.showMessagePreview"),
|
||||
);
|
||||
|
||||
const toggleMessagePreview = useCallback((): void => {
|
||||
setShouldShowMessagePreview((current) => {
|
||||
const toggled = !current;
|
||||
SettingsStore.setValue("RoomList.showMessagePreview", null, SettingLevel.DEVICE, toggled);
|
||||
return toggled;
|
||||
});
|
||||
}, []);
|
||||
|
||||
return { toggleMessagePreview, shouldShowMessagePreview };
|
||||
}
|
||||
@@ -314,6 +314,7 @@ export interface Settings {
|
||||
"showImages": IBaseSetting<boolean>;
|
||||
"showAvatarsOnInvites": IBaseSetting<boolean>;
|
||||
"RoomList.preferredSorting": IBaseSetting<SortingAlgorithm>;
|
||||
"RoomList.showMessagePreview": IBaseSetting<boolean>;
|
||||
"RightPanel.phasesGlobal": IBaseSetting<IRightPanelForRoomStored | null>;
|
||||
"RightPanel.phases": IBaseSetting<IRightPanelForRoomStored | null>;
|
||||
"enableEventIndexing": IBaseSetting<boolean>;
|
||||
@@ -1126,6 +1127,10 @@ export const SETTINGS: Settings = {
|
||||
supportedLevels: [SettingLevel.DEVICE],
|
||||
default: SortingAlgorithm.Recency,
|
||||
},
|
||||
"RoomList.showMessagePreview": {
|
||||
supportedLevels: [SettingLevel.DEVICE],
|
||||
default: false,
|
||||
},
|
||||
"RightPanel.phasesGlobal": {
|
||||
supportedLevels: [SettingLevel.DEVICE],
|
||||
default: null,
|
||||
|
||||
@@ -218,4 +218,26 @@ describe("RoomListViewModel", () => {
|
||||
expect(vm.current.activeSortOption).toEqual(SortOption.AToZ);
|
||||
});
|
||||
});
|
||||
|
||||
describe("message preview toggle", () => {
|
||||
it("should return shouldShowMessagePreview based on setting", () => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation(() => true);
|
||||
mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
expect(vm.current.shouldShowMessagePreview).toEqual(true);
|
||||
});
|
||||
|
||||
it("should change setting on toggle", () => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation(() => true);
|
||||
const fn = jest.spyOn(SettingsStore, "setValue").mockImplementation(async () => {});
|
||||
mockAndCreateRooms();
|
||||
const { result: vm } = renderHook(() => useRoomListViewModel());
|
||||
expect(vm.current.shouldShowMessagePreview).toEqual(true);
|
||||
act(() => {
|
||||
vm.current.toggleMessagePreview();
|
||||
});
|
||||
expect(vm.current.shouldShowMessagePreview).toEqual(false);
|
||||
expect(fn).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,6 +35,8 @@ describe("<RoomList />", () => {
|
||||
activeSecondaryFilter: SecondaryFilters.AllActivity,
|
||||
sort: jest.fn(),
|
||||
activeSortOption: SortOption.Activity,
|
||||
shouldShowMessagePreview: false,
|
||||
toggleMessagePreview: jest.fn(),
|
||||
};
|
||||
|
||||
// Needed to render a room list cell
|
||||
|
||||
@@ -28,6 +28,8 @@ describe("<RoomListPrimaryFilters />", () => {
|
||||
activeSecondaryFilter: SecondaryFilters.AllActivity,
|
||||
sort: jest.fn(),
|
||||
activeSortOption: SortOption.Activity,
|
||||
shouldShowMessagePreview: false,
|
||||
toggleMessagePreview: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user