Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/app/components/message/MessageJumpLink.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { style } from '@vanilla-extract/css';

export const messageJumpLink = style({
':hover': {
cursor: 'pointer',
textDecoration: 'underline',
},
});
13 changes: 13 additions & 0 deletions src/app/components/message/MessageJumpLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import { messageJumpLink } from "./MessageJumpLink.css";
import { useRoomNavigate } from "../../hooks/useRoomNavigate";

export function MessageJumpLink({ roomId, eventId }: { roomId: string, eventId: string }) {
const { navigateRoom } = useRoomNavigate();

return (
<button type="button" className={messageJumpLink} onClick={() => navigateRoom(roomId, eventId)}>
a message
</button>
);
}
43 changes: 43 additions & 0 deletions src/app/features/room/RoomTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ import { useAccessiblePowerTagColors, useGetMemberPowerTag } from '../../hooks/u
import { useTheme } from '../../hooks/useTheme';
import { useRoomCreatorsTag } from '../../hooks/useRoomCreatorsTag';
import { usePowerLevelTags } from '../../hooks/usePowerLevelTags';
import { usePinnedEventParser } from '../../hooks/usePinnedEventParser';

const TimelineFloat = as<'div', css.TimelineFloatVariants>(
({ position, className, ...props }, ref) => (
Expand Down Expand Up @@ -532,6 +533,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
[mx, room, linkifyOpts, spoilerClickHandler, mentionClickHandler, useAuthentication]
);
const parseMemberEvent = useMemberEventParser();
const parsePinnedEvent = usePinnedEventParser(room.roomId);

const [timeline, setTimeline] = useState<Timeline>(() =>
eventId ? getEmptyTimeline() : getInitialTimeline(room)
Expand Down Expand Up @@ -1468,6 +1470,47 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
</Event>
);
},
[StateEvent.RoomPinnedEvents]: (mEventId, mEvent, item) => {
const highlighted = focusItem?.index === item && focusItem.highlight;
const parsed = parsePinnedEvent(mEvent);

const timeJSX = (
<Time
ts={mEvent.getTs()}
compact={messageLayout === MessageLayout.Compact}
hour24Clock={hour24Clock}
dateFormatString={dateFormatString}
/>
);

return (
<Event
key={mEvent.getId()}
data-message-item={item}
data-message-id={mEventId}
room={room}
mEvent={mEvent}
highlight={highlighted}
messageSpacing={messageSpacing}
canDelete={canRedact || mEvent.getSender() === mx.getUserId()}
hideReadReceipts={hideActivity}
showDeveloperTools={showDeveloperTools}
>
<EventContent
messageLayout={messageLayout}
time={timeJSX}
iconSrc={Icons.Pin}
content={
<Box grow="Yes" direction="Column">
<Text size="T300" priority="300">
{parsed}
</Text>
</Box>
}
/>
</Event>
);
}
},
(mEventId, mEvent, item) => {
if (!showHiddenEvents) return null;
Expand Down
57 changes: 57 additions & 0 deletions src/app/hooks/usePinnedEventParser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { MatrixEvent } from 'matrix-js-sdk';
import React, { ReactNode } from 'react';
import { IRoomPinnedEventsContent } from '../../types/matrix/room';
import { getMxIdLocalPart } from '../utils/matrix';
import { MessageJumpLink } from '../components/message/MessageJumpLink';

export type PinnedEventParser = (mEvent: MatrixEvent) => ReactNode;

export const usePinnedEventParser = (roomId: string): PinnedEventParser => {
const pinnedEventParser = (mEvent: MatrixEvent) => {
const { pinned } = mEvent.getContent<IRoomPinnedEventsContent>();
const prevPinned = (mEvent.getPrevContent() as Partial<IRoomPinnedEventsContent>).pinned;
const senderId = mEvent.getSender() ?? '';
const senderName = getMxIdLocalPart(senderId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use

getMemberDisplayName(room, senderId) ??
    getMxIdLocalPart(senderId) ??
    senderId;

for displayname


const addedPins = pinned.filter((pdu) => !(prevPinned?.includes(pdu) ?? false));
const removedPins = prevPinned?.filter((pdu) => !pinned.includes(pdu)) ?? [];

return (
<>
<b>{senderName}</b>
{addedPins.length === 0 && removedPins.length === 0 ? (
' made no changes to the pinned messages'
) : (
<>
{addedPins.length > 0 && (
<>
{' pinned '}
<b>
{addedPins.length === 1 ? (
<MessageJumpLink roomId={roomId} eventId={addedPins[0]} />
) : (
`${addedPins.length} messages`
)}
</b>
</>
)}
{addedPins.length > 0 && removedPins.length > 0 && 'and'}
{removedPins.length > 0 && (
<>
{' unpinned '}
<b>
{removedPins.length === 1 ? (
<MessageJumpLink roomId={roomId} eventId={removedPins[0]} />
) : (
`${removedPins.length} messages`
)}
</b>
</>
)}
</>
)}
</>
);
};
return pinnedEventParser;
};
4 changes: 4 additions & 0 deletions src/types/matrix/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ export type IRoomCreateContent = {
};
};

export type IRoomPinnedEventsContent = {
pinned: string[];
};

export type GetContentCallback = <T>() => T;

export type RoomToParents = Map<string, Set<string>>;
Expand Down