Files
ThreadNet-Web/src/components/viewmodels/roomlist/RoomListItemMenuViewModel.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

181 lines
5.5 KiB
TypeScript
Raw Normal View History

/*
* 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 } from "react";
import { type Room, RoomEvent } from "matrix-js-sdk/src/matrix";
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
import { useUnreadNotifications } from "../../../hooks/useUnreadNotifications";
import { hasAccessToOptionsMenu } from "./utils";
import DMRoomMap from "../../../utils/DMRoomMap";
import { DefaultTagID } from "../../../stores/room-list/models";
import { NotificationLevel } from "../../../stores/notifications/NotificationLevel";
import { shouldShowComponent } from "../../../customisations/helpers/UIComponents";
import { UIComponent } from "../../../settings/UIFeature";
import dispatcher from "../../../dispatcher/dispatcher";
import { clearRoomNotification, setMarkedUnreadState } from "../../../utils/notifications";
import PosthogTrackers from "../../../PosthogTrackers";
import { tagRoom } from "../../../utils/room/tagRoom";
export interface RoomListItemMenuViewState {
/**
* Whether the more options menu should be shown.
*/
showMoreOptionsMenu: boolean;
/**
* Whether the room is a favourite room.
*/
isFavourite: boolean;
/**
* Can invite other user's in the room.
*/
canInvite: boolean;
/**
* Can copy the room link.
*/
canCopyRoomLink: boolean;
/**
* Can mark the room as read.
*/
canMarkAsRead: boolean;
/**
* Can mark the room as unread.
*/
canMarkAsUnread: boolean;
/**
* Mark the room as read.
* @param evt
*/
markAsRead: (evt: Event) => void;
/**
* Mark the room as unread.
* @param evt
*/
markAsUnread: (evt: Event) => void;
/**
* Toggle the room as favourite.
* @param evt
*/
toggleFavorite: (evt: Event) => void;
/**
* Toggle the room as low priority.
*/
toggleLowPriority: () => void;
/**
* Invite other users in the room.
* @param evt
*/
invite: (evt: Event) => void;
/**
* Copy the room link in the clipboard.
* @param evt
*/
copyRoomLink: (evt: Event) => void;
/**
* Leave the room.
* @param evt
*/
leaveRoom: (evt: Event) => void;
}
export function useRoomListItemMenuViewModel(room: Room): RoomListItemMenuViewState {
const matrixClient = useMatrixClientContext();
const roomTags = useEventEmitterState(room, RoomEvent.Tags, () => room.tags);
const { level: notificationLevel } = useUnreadNotifications(room);
const showMoreOptionsMenu = hasAccessToOptionsMenu(room);
const isDm = Boolean(DMRoomMap.shared().getUserIdForRoomId(room.roomId));
const isFavourite = Boolean(roomTags[DefaultTagID.Favourite]);
const isArchived = Boolean(roomTags[DefaultTagID.Archived]);
const canMarkAsRead = notificationLevel > NotificationLevel.None;
const canMarkAsUnread = !canMarkAsRead && !isArchived;
const canInvite =
room.canInvite(matrixClient.getUserId()!) && !isDm && shouldShowComponent(UIComponent.InviteUsers);
const canCopyRoomLink = !isDm;
// Actions
const markAsRead = useCallback(
async (evt: Event): Promise<void> => {
await clearRoomNotification(room, matrixClient);
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuMarkRead", evt);
},
[room, matrixClient],
);
const markAsUnread = useCallback(
async (evt: Event): Promise<void> => {
await setMarkedUnreadState(room, matrixClient, true);
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuMarkUnread", evt);
},
[room, matrixClient],
);
const toggleFavorite = useCallback(
(evt: Event): void => {
tagRoom(room, DefaultTagID.Favourite);
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuFavouriteToggle", evt);
},
[room],
);
const toggleLowPriority = useCallback((): void => tagRoom(room, DefaultTagID.LowPriority), [room]);
const invite = useCallback(
(evt: Event): void => {
dispatcher.dispatch({
action: "view_invite",
roomId: room.roomId,
});
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuInviteItem", evt);
},
[room],
);
const copyRoomLink = useCallback(
(evt: Event): void => {
dispatcher.dispatch({
action: "copy_room",
room_id: room.roomId,
});
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuFavouriteToggle", evt);
},
[room],
);
const leaveRoom = useCallback(
(evt: Event): void => {
dispatcher.dispatch({
action: isArchived ? "forget_room" : "leave_room",
room_id: room.roomId,
});
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuLeaveItem", evt);
},
[room, isArchived],
);
return {
showMoreOptionsMenu,
isFavourite,
canInvite,
canCopyRoomLink,
canMarkAsRead,
canMarkAsUnread,
markAsRead,
markAsUnread,
toggleFavorite,
toggleLowPriority,
invite,
copyRoomLink,
leaveRoom,
};
}