From 7022f7e0db92c2f74b58b6b2f789c12f8e71674b Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 7 Dec 2024 20:15:34 +0530 Subject: [PATCH] room pinned message - WIP --- .../room-pin-menu/RoomPinMenu.css.ts | 6 ++ .../components/room-pin-menu/RoomPinMenu.tsx | 43 ++++++++++++ src/app/components/room-pin-menu/index.ts | 1 + src/app/features/room/RoomViewHeader.tsx | 69 ++++++++++++++++++- 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 src/app/components/room-pin-menu/RoomPinMenu.css.ts create mode 100644 src/app/components/room-pin-menu/RoomPinMenu.tsx create mode 100644 src/app/components/room-pin-menu/index.ts diff --git a/src/app/components/room-pin-menu/RoomPinMenu.css.ts b/src/app/components/room-pin-menu/RoomPinMenu.css.ts new file mode 100644 index 000000000..d57fdf8a5 --- /dev/null +++ b/src/app/components/room-pin-menu/RoomPinMenu.css.ts @@ -0,0 +1,6 @@ +import { style } from '@vanilla-extract/css'; +import { config } from 'folds'; + +export const PinMenuHeader = style({ + paddingLeft: config.space.S300, +}); diff --git a/src/app/components/room-pin-menu/RoomPinMenu.tsx b/src/app/components/room-pin-menu/RoomPinMenu.tsx new file mode 100644 index 000000000..7639f1639 --- /dev/null +++ b/src/app/components/room-pin-menu/RoomPinMenu.tsx @@ -0,0 +1,43 @@ +import React, { forwardRef } from 'react'; +import { Room } from 'matrix-js-sdk'; +import { Box, Header, Menu, Scroll, Text, toRem } from 'folds'; +import { useRoomPinnedEvents } from '../../hooks/useRoomPinnedEvents'; +import * as css from './RoomPinMenu.css'; + +type RoomPinMenuProps = { + room: Room; + requestClose: () => void; +}; +export const RoomPinMenu = forwardRef( + ({ room, requestClose }, ref) => { + const pinnedEvents = useRoomPinnedEvents(room); + const pinnedData = pinnedEvents.map((eventId) => room.findEventById(eventId) ?? eventId); + + return ( + +
+ + Pinned Messages + + + + +
+ + + {pinnedData.map((data) => { + if (typeof data === 'string') return

{data}

; + + return

{data.getContent().body}

; + })} +
+
+
+ ); + } +); diff --git a/src/app/components/room-pin-menu/index.ts b/src/app/components/room-pin-menu/index.ts new file mode 100644 index 000000000..65ddaeea1 --- /dev/null +++ b/src/app/components/room-pin-menu/index.ts @@ -0,0 +1 @@ +export * from './RoomPinMenu'; diff --git a/src/app/features/room/RoomViewHeader.tsx b/src/app/features/room/RoomViewHeader.tsx index ae80deb6e..7900ad29a 100644 --- a/src/app/features/room/RoomViewHeader.tsx +++ b/src/app/features/room/RoomViewHeader.tsx @@ -19,6 +19,7 @@ import { Line, PopOut, RectCords, + Badge, } from 'folds'; import { useNavigate } from 'react-router-dom'; import { JoinRule, Room } from 'matrix-js-sdk'; @@ -54,6 +55,8 @@ import { getMatrixToRoom } from '../../plugins/matrix-to'; import { getViaServers } from '../../plugins/via-servers'; import { BackRouteHandler } from '../../components/BackRouteHandler'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; +import { useRoomPinnedEvents } from '../../hooks/useRoomPinnedEvents'; +import { RoomPinMenu } from '../../components/room-pin-menu'; type RoomMenuProps = { room: Room; @@ -180,14 +183,18 @@ export function RoomViewHeader() { const room = useRoom(); const space = useSpaceOptionally(); const [menuAnchor, setMenuAnchor] = useState(); + const [pinMenuAnchor, setPinMenuAnchor] = useState(); const mDirects = useAtomValue(mDirectAtom); + const pinnedEvents = useRoomPinnedEvents(room); const encryptionEvent = useStateEvent(room, StateEvent.RoomEncryption); const ecryptedRoom = !!encryptionEvent; const avatarMxc = useRoomAvatar(room, mDirects.has(room.roomId)); const name = useRoomName(room); const topic = useRoomTopic(room); - const avatarUrl = avatarMxc ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined : undefined; + const avatarUrl = avatarMxc + ? mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined + : undefined; const setPeopleDrawer = useSetSetting(settingsAtom, 'isPeopleDrawer'); @@ -205,6 +212,10 @@ export function RoomViewHeader() { setMenuAnchor(evt.currentTarget.getBoundingClientRect()); }; + const handleOpenPinMenu: MouseEventHandler = (evt) => { + setPinMenuAnchor(evt.currentTarget.getBoundingClientRect()); + }; + return ( @@ -297,6 +308,62 @@ export function RoomViewHeader() { )} )} + {pinnedEvents.length > 0 && ( + + Pinned Messages + + } + > + {(triggerRef) => ( + + + + {pinnedEvents.length} + + + + + )} + + )} + setPinMenuAnchor(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + escapeDeactivates: stopPropagation, + }} + > + setPinMenuAnchor(undefined)} /> + + } + /> {screenSize === ScreenSize.Desktop && (