Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into 27981-add-error-di…
Browse files Browse the repository at this point in the history
…alog-for-room-publish-toggle
  • Loading branch information
sahil9001 committed Sep 5, 2024
2 parents 3e76c26 + 1e3320d commit 38ae39d
Show file tree
Hide file tree
Showing 11 changed files with 532 additions and 168 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/playwright-image-updates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6
uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 # v7
with:
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
branch: actions/playwright-image-updates
Expand Down
7 changes: 6 additions & 1 deletion res/css/views/rooms/_PinnedEventTile.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ limitations under the License.
display: flex;
flex-direction: column;
gap: var(--cpd-space-1x);
width: 100%;
/* Remove avatar width and space between the avatar and the wrapper */
/* We need it to make the location fit */
width: calc(100% - var(--cpd-space-4x) - 32px);
/* Prevent a long sender name to overflow the tile */
overflow: hidden;

.mx_PinnedEventTile_top {
display: flex;
Expand All @@ -35,6 +39,7 @@ limitations under the License.
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font: var(--cpd-font-body-md-semibold);
}
}

Expand Down
4 changes: 4 additions & 0 deletions res/css/views/rooms/_PinnedMessageBanner.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

.mx_PinnedMessageBanner_prefix {
font: var(--cpd-font-body-sm-semibold);
}
}

.mx_PinnedMessageBanner_redactedMessage {
Expand Down
14 changes: 6 additions & 8 deletions src/components/views/rooms/PinnedEventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ limitations under the License.

import React, { JSX, useCallback, useState } from "react";
import { EventTimeline, EventType, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import { IconButton, Menu, MenuItem, Separator, Text } from "@vector-im/compound-web";
import { IconButton, Menu, MenuItem, Separator, Tooltip } from "@vector-im/compound-web";
import { Icon as ViewIcon } from "@vector-im/compound-design-tokens/icons/visibility-on.svg";
import { Icon as UnpinIcon } from "@vector-im/compound-design-tokens/icons/unpin.svg";
import { Icon as ForwardIcon } from "@vector-im/compound-design-tokens/icons/forward.svg";
Expand Down Expand Up @@ -86,13 +86,11 @@ export function PinnedEventTile({ event, room, permalinkCreator }: PinnedEventTi
</div>
<div className="mx_PinnedEventTile_wrapper">
<div className="mx_PinnedEventTile_top">
<Text
weight="semibold"
className={classNames("mx_PinnedEventTile_sender", getUserNameColorClass(sender))}
as="span"
>
{event.sender?.name || sender}
</Text>
<Tooltip label={event.sender?.name || sender}>
<span className={classNames("mx_PinnedEventTile_sender", getUserNameColorClass(sender))}>
{event.sender?.name || sender}
</span>
</Tooltip>
<PinMenu event={event} room={room} permalinkCreator={permalinkCreator} />
</div>
<MessageEvent
Expand Down
90 changes: 81 additions & 9 deletions src/components/views/rooms/PinnedMessageBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import React, { JSX, useEffect, useMemo, useState } from "react";
import { Icon as PinIcon } from "@vector-im/compound-design-tokens/icons/pin-solid.svg";
import { Button } from "@vector-im/compound-web";
import { Room } from "matrix-js-sdk/src/matrix";
import { M_POLL_START, MatrixEvent, MsgType, Room } from "matrix-js-sdk/src/matrix";
import classNames from "classnames";

import { usePinnedEvents, useSortedFetchedPinnedEvents } from "../../../hooks/usePinnedEvents";
Expand Down Expand Up @@ -59,16 +59,10 @@ export function PinnedMessageBanner({ room, permalinkCreator }: PinnedMessageBan
const [currentEventIndex, setCurrentEventIndex] = useState(eventCount - 1);
// When the number of pinned messages changes, we want to display the last message
useEffect(() => {
setCurrentEventIndex((currentEventIndex) => eventCount - 1);
setCurrentEventIndex(() => eventCount - 1);
}, [eventCount]);

const pinnedEvent = pinnedEvents[currentEventIndex];
// Generate a preview for the pinned event
const eventPreview = useMemo(() => {
if (!pinnedEvent || pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure()) return null;
return MessagePreviewStore.instance.generatePreviewForEvent(pinnedEvent);
}, [pinnedEvent]);

if (!pinnedEvent) return null;

const shouldUseMessageEvent = pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure();
Expand Down Expand Up @@ -116,7 +110,7 @@ export function PinnedMessageBanner({ room, permalinkCreator }: PinnedMessageBan
)}
</div>
)}
{eventPreview && <span className="mx_PinnedMessageBanner_message">{eventPreview}</span>}
<EventPreview pinnedEvent={pinnedEvent} />
{/* In case of redacted event, we want to display the nice sentence of the message event like in the timeline or in the pinned message list */}
{shouldUseMessageEvent && (
<div className="mx_PinnedMessageBanner_redactedMessage">
Expand All @@ -135,6 +129,84 @@ export function PinnedMessageBanner({ room, permalinkCreator }: PinnedMessageBan
);
}

/**
* The props for the {@link EventPreview} component.
*/
interface EventPreviewProps {
/**
* The pinned event to display the preview for
*/
pinnedEvent: MatrixEvent;
}

/**
* A component that displays a preview for the pinned event.
*/
function EventPreview({ pinnedEvent }: EventPreviewProps): JSX.Element | null {
const preview = useEventPreview(pinnedEvent);
if (!preview) return null;

const prefix = getPreviewPrefix(pinnedEvent.getType(), pinnedEvent.getContent().msgtype as MsgType);
if (!prefix)
return (
<span className="mx_PinnedMessageBanner_message" data-testid="banner-message">
{preview}
</span>
);

return (
<span className="mx_PinnedMessageBanner_message" data-testid="banner-message">
{_t(
"room|pinned_message_banner|preview",
{
prefix,
preview,
},
{
bold: (sub) => <span className="mx_PinnedMessageBanner_prefix">{sub}</span>,
},
)}
</span>
);
}

/**
* Hooks to generate a preview for the pinned event.
* @param pinnedEvent
*/
function useEventPreview(pinnedEvent: MatrixEvent | null): string | null {
return useMemo(() => {
if (!pinnedEvent || pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure()) return null;
return MessagePreviewStore.instance.generatePreviewForEvent(pinnedEvent);
}, [pinnedEvent]);
}

/**
* Get the prefix for the preview based on the type and the message type.
* @param type
* @param msgType
*/
function getPreviewPrefix(type: string, msgType: MsgType): string | null {
switch (type) {
case M_POLL_START.name:
return _t("room|pinned_message_banner|prefix|poll");
default:
}

switch (msgType) {
case MsgType.Audio:
return _t("room|pinned_message_banner|prefix|audio");
case MsgType.Image:
return _t("room|pinned_message_banner|prefix|image");
case MsgType.Video:
return _t("room|pinned_message_banner|prefix|video");
case MsgType.File:
return _t("room|pinned_message_banner|prefix|file");
default:
return null;
}
}

const MAX_INDICATORS = 3;

/**
Expand Down
8 changes: 8 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,14 @@
"button_view_all": "View all",
"description": "This room has pinned messages. Click to view them.",
"go_to_message": "View the pinned message in the timeline.",
"prefix": {
"audio": "Audio",
"file": "File",
"image": "Image",
"poll": "Poll",
"video": "Video"
},
"preview": "<bold>%(prefix)s:</bold> %(preview)s",
"title": "<bold>%(index)s of %(length)s</bold> Pinned messages"
},
"read_topic": "Click to read topic",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
class="mx_PinnedEventTile_top"
>
<span
class="_typography_yh5dq_162 _font-body-md-semibold_yh5dq_64 mx_PinnedEventTile_sender mx_Username_color3"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
Expand Down Expand Up @@ -218,7 +218,7 @@ exports[`<PinnedMessagesCard /> should show two pinned messages 1`] = `
class="mx_PinnedEventTile_top"
>
<span
class="_typography_yh5dq_162 _font-body-md-semibold_yh5dq_64 mx_PinnedEventTile_sender mx_Username_color3"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
Expand Down Expand Up @@ -347,7 +347,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
class="mx_PinnedEventTile_top"
>
<span
class="_typography_yh5dq_162 _font-body-md-semibold_yh5dq_64 mx_PinnedEventTile_sender mx_Username_color3"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
Expand Down Expand Up @@ -413,7 +413,7 @@ exports[`<PinnedMessagesCard /> unpin all should not allow to unpinall 1`] = `
class="mx_PinnedEventTile_top"
>
<span
class="_typography_yh5dq_162 _font-body-md-semibold_yh5dq_64 mx_PinnedEventTile_sender mx_Username_color3"
class="mx_PinnedEventTile_sender mx_Username_color3"
>
@alice:example.org
</span>
Expand Down
28 changes: 27 additions & 1 deletion test/components/views/rooms/PinnedMessageBanner-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import userEvent from "@testing-library/user-event";
import * as pinnedEventHooks from "../../../../src/hooks/usePinnedEvents";
import { PinnedMessageBanner } from "../../../../src/components/views/rooms/PinnedMessageBanner";
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
import { stubClient } from "../../../test-utils";
import { makePollStartEvent, stubClient } from "../../../test-utils";
import dis from "../../../../src/dispatcher/dispatcher";
import RightPanelStore from "../../../../src/stores/right-panel/RightPanelStore";
import { RightPanelPhases } from "../../../../src/stores/right-panel/RightPanelStorePhases";
Expand Down Expand Up @@ -185,6 +185,32 @@ describe("<PinnedMessageBanner />", () => {
});
});

it.each([
["m.file", "File"],
["m.audio", "Audio"],
["m.video", "Video"],
["m.image", "Image"],
])("should display the %s event type", (msgType, label) => {
const body = `Message with ${msgType} type`;
const event = makePinEvent({ content: { body, msgtype: msgType } });
jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event.getId()!]);
jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event]);

const { asFragment } = renderBanner();
expect(screen.getByTestId("banner-message")).toHaveTextContent(`${label}: ${body}`);
expect(asFragment()).toMatchSnapshot();
});

it("should display display a poll event", async () => {
const event = makePollStartEvent("Alice?", userId);
jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event.getId()!]);
jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event]);

const { asFragment } = renderBanner();
expect(screen.getByTestId("banner-message")).toHaveTextContent("Poll: Alice?");
expect(asFragment()).toMatchSnapshot();
});

describe("Right button", () => {
beforeEach(() => {
jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event1.getId()!, event2.getId()!]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ exports[`<PinnedEventTile /> should render pinned event 1`] = `
class="mx_PinnedEventTile_top"
>
<span
class="_typography_yh5dq_162 _font-body-md-semibold_yh5dq_64 mx_PinnedEventTile_sender mx_Username_color2"
class="mx_PinnedEventTile_sender mx_Username_color2"
>
@alice:server.org
</span>
Expand Down Expand Up @@ -90,7 +90,7 @@ exports[`<PinnedEventTile /> should render pinned event with thread info 1`] = `
class="mx_PinnedEventTile_top"
>
<span
class="_typography_yh5dq_162 _font-body-md-semibold_yh5dq_64 mx_PinnedEventTile_sender mx_Username_color2"
class="mx_PinnedEventTile_sender mx_Username_color2"
>
@alice:server.org
</span>
Expand Down
Loading

0 comments on commit 38ae39d

Please sign in to comment.