Skip to content

Commit

Permalink
Unlabs feature pinning (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
florianduros authored Sep 16, 2024
1 parent 74885c9 commit 5985277
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 99 deletions.
1 change: 0 additions & 1 deletion src/TextForEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,6 @@ const onPinnedMessagesClick = (): void => {
};

function textForPinnedEvent(event: MatrixEvent, client: MatrixClient, allowJSX: boolean): (() => Renderable) | null {
if (!SettingsStore.getValue("feature_pinning")) return null;
const senderName = getSenderName(event);
const roomId = event.getRoomId()!;

Expand Down
3 changes: 1 addition & 2 deletions src/components/structures/RightPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import RightPanelStore from "../../stores/right-panel/RightPanelStore";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import RoomSummaryCard from "../views/right_panel/RoomSummaryCard";
import WidgetCard from "../views/right_panel/WidgetCard";
import SettingsStore from "../../settings/SettingsStore";
import MemberList from "../views/rooms/MemberList";
import UserInfo from "../views/right_panel/UserInfo";
import ThirdPartyMemberInfo from "../views/rooms/ThirdPartyMemberInfo";
Expand Down Expand Up @@ -220,7 +219,7 @@ export default class RightPanel extends React.Component<Props, IState> {
break;

case RightPanelPhases.PinnedMessages:
if (!!this.props.room && SettingsStore.getValue("feature_pinning")) {
if (!!this.props.room) {
card = (
<PinnedMessagesCard
room={this.props.room}
Expand Down
10 changes: 3 additions & 7 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2408,13 +2408,9 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
</AuxPanel>
);

const isPinningEnabled = SettingsStore.getValue<boolean>("feature_pinning");
let pinnedMessageBanner;
if (isPinningEnabled) {
pinnedMessageBanner = (
<PinnedMessageBanner room={this.state.room} permalinkCreator={this.permalinkCreator} />
);
}
const pinnedMessageBanner = (
<PinnedMessageBanner room={this.state.room} permalinkCreator={this.permalinkCreator} />
);

let messageComposer;
const showComposer =
Expand Down
3 changes: 1 addition & 2 deletions src/components/structures/grouper/MainGrouper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import DateSeparator from "../../views/messages/DateSeparator";
import HistoryTile from "../../views/rooms/HistoryTile";
import EventListSummary from "../../views/elements/EventListSummary";
import { SeparatorKind } from "../../views/messages/TimelineSeparator";
import SettingsStore from "../../../settings/SettingsStore";

const groupedStateEvents = [
EventType.RoomMember,
Expand Down Expand Up @@ -91,7 +90,7 @@ export class MainGrouper extends BaseGrouper {
return;
}

if (ev.getType() === EventType.RoomPinnedEvents && !SettingsStore.getValue("feature_pinning")) {
if (ev.getType() === EventType.RoomPinnedEvents) {
// If pinned messages are disabled, don't show the summary
return;
}
Expand Down
6 changes: 2 additions & 4 deletions src/components/views/context_menus/RoomContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { EchoChamber } from "../../../stores/local-echo/EchoChamber";
import { RoomNotifState } from "../../../RoomNotifs";
import Modal from "../../../Modal";
import ExportDialog from "../dialogs/ExportDialog";
import { useFeatureEnabled } from "../../../hooks/useSettings";
import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases";
import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog";
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
Expand Down Expand Up @@ -261,11 +260,10 @@ const RoomContextMenu: React.FC<IProps> = ({ room, onFinished, ...props }) => {
);
}

const pinningEnabled = useFeatureEnabled("feature_pinning");
const pinCount = usePinnedEvents(pinningEnabled ? room : undefined)?.length;
const pinCount = usePinnedEvents(room).length;

let pinsOption: JSX.Element | undefined;
if (pinningEnabled && !isVideoRoom) {
if (!isVideoRoom) {
pinsOption = (
<IconizedContextMenuOption
onClick={(ev: ButtonEvent) => {
Expand Down
22 changes: 10 additions & 12 deletions src/components/views/right_panel/LegacyRoomHeaderButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePha
import { ActionPayload } from "../../../dispatcher/payloads";
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
import { showThreadPanel } from "../../../dispatcher/dispatch-actions/threads";
import SettingsStore from "../../../settings/SettingsStore";
import {
RoomNotificationStateStore,
UPDATE_STATUS_INDICATOR,
Expand Down Expand Up @@ -245,17 +244,16 @@ export default class LegacyRoomHeaderButtons extends HeaderButtons<IProps> {

const rightPanelPhaseButtons: Map<RightPanelPhases, any> = new Map();

if (SettingsStore.getValue("feature_pinning")) {
rightPanelPhaseButtons.set(
RightPanelPhases.PinnedMessages,
<PinnedMessagesHeaderButton
key="pinnedMessagesButton"
room={this.props.room}
isHighlighted={this.isPhase(RightPanelPhases.PinnedMessages)}
onClick={this.onPinnedMessagesClicked}
/>,
);
}
rightPanelPhaseButtons.set(
RightPanelPhases.PinnedMessages,
<PinnedMessagesHeaderButton
key="pinnedMessagesButton"
room={this.props.room}
isHighlighted={this.isPhase(RightPanelPhases.PinnedMessages)}
onClick={this.onPinnedMessagesClicked}
/>,
);

rightPanelPhaseButtons.set(
RightPanelPhases.Timeline,
<TimelineCardHeaderButton
Expand Down
25 changes: 11 additions & 14 deletions src/components/views/right_panel/RoomSummaryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import { useEventEmitterState } from "../../../hooks/useEventEmitter";
import { E2EStatus } from "../../../utils/ShieldUtils";
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
import { useFeatureEnabled } from "../../../hooks/useSettings";
import RoomName from "../elements/RoomName";
import ExportDialog from "../dialogs/ExportDialog";
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
Expand Down Expand Up @@ -314,8 +313,7 @@ const RoomSummaryCard: React.FC<IProps> = ({
</header>
);

const pinningEnabled = useFeatureEnabled("feature_pinning");
const pinCount = usePinnedEvents(pinningEnabled ? room : undefined)?.length;
const pinCount = usePinnedEvents(room).length;

const roomTags = useEventEmitterState(RoomListStore.instance, LISTS_UPDATE_EVENT, () =>
RoomListStore.instance.getTagsForRoom(room),
Expand Down Expand Up @@ -382,17 +380,16 @@ const RoomSummaryCard: React.FC<IProps> = ({

{!isVideoRoom && (
<>
{pinningEnabled && (
<MenuItem
Icon={PinIcon}
label={_t("right_panel|pinned_messages_button")}
onSelect={onRoomPinsClick}
>
<Text as="span" size="sm">
{pinCount}
</Text>
</MenuItem>
)}
<MenuItem
Icon={PinIcon}
label={_t("right_panel|pinned_messages_button")}
onSelect={onRoomPinsClick}
>
<Text as="span" size="sm">
{pinCount}
</Text>
</MenuItem>

<MenuItem Icon={FilesIcon} label={_t("right_panel|files_button")} onSelect={onRoomFilesClick} />
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,13 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
[EventType.RoomServerAcl]: _td("room_settings|permissions|m.room.server_acl"),
[EventType.Reaction]: _td("room_settings|permissions|m.reaction"),
[EventType.RoomRedaction]: _td("room_settings|permissions|m.room.redaction"),
[EventType.RoomPinnedEvents]: _td("room_settings|permissions|m.room.pinned_events"),

// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
"im.vector.modular.widgets": isSpaceRoom ? null : _td("room_settings|permissions|m.widget"),
[VoiceBroadcastInfoEventType]: _td("room_settings|permissions|io.element.voice_broadcast_info"),
};

if (SettingsStore.getValue("feature_pinning")) {
plEventsToLabels[EventType.RoomPinnedEvents] = _td("room_settings|permissions|m.room.pinned_events");
}
// MSC3401: Native Group VoIP signaling
if (SettingsStore.getValue("feature_group_calls")) {
plEventsToLabels[ElementCall.CALL_EVENT_TYPE.name] = _td("room_settings|permissions|m.call");
Expand Down
1 change: 0 additions & 1 deletion src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,6 @@
"notifications": "Enable the notifications panel in the room header",
"oidc_native_flow": "OIDC native authentication",
"oidc_native_flow_description": "⚠ WARNING: Experimental. Use OIDC native authentication when supported by the server.",
"pinning": "Message Pinning",
"release_announcement": "Release announcement",
"render_reaction_images": "Render custom images in reactions",
"render_reaction_images_description": "Sometimes referred to as \"custom emojis\".",
Expand Down
8 changes: 0 additions & 8 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,6 @@ export const SETTINGS: { [setting: string]: ISetting } = {
supportedLevelsAreOrdered: true,
default: false,
},
"feature_pinning": {
isFeature: true,
labsGroup: LabGroup.Messaging,
displayName: _td("labs|pinning"),
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG_PRIORITISED,
supportedLevelsAreOrdered: true,
default: true,
},
"feature_wysiwyg_composer": {
isFeature: true,
labsGroup: LabGroup.Messaging,
Expand Down
2 changes: 0 additions & 2 deletions src/utils/PinningUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
import { MatrixEvent, EventType, M_POLL_START, MatrixClient, EventTimeline, Room } from "matrix-js-sdk/src/matrix";

import { isContentActionable } from "./EventUtils";
import SettingsStore from "../settings/SettingsStore";
import { ReadPinsEventId } from "../components/views/right_panel/types";

export default class PinningUtils {
Expand Down Expand Up @@ -70,7 +69,6 @@ export default class PinningUtils {
* @private
*/
private static canPinOrUnpin(matrixClient: MatrixClient, mxEvent: MatrixEvent): boolean {
if (!SettingsStore.getValue("feature_pinning")) return false;
if (!isContentActionable(mxEvent)) return false;

const room = matrixClient.getRoom(mxEvent.getRoomId());
Expand Down
5 changes: 0 additions & 5 deletions test/TextForEvent-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ describe("TextForEvent", () => {
});

describe("TextForPinnedEvent", () => {
beforeAll(() => {
// enable feature_pinning setting
(SettingsStore.getValue as jest.Mock).mockImplementation((feature) => feature === "feature_pinning");
});

it("mentions message when a single message was pinned, with no previously pinned messages", () => {
const event = mockPinnedEvent(["message-1"]);
const plainText = textForEvent(event, mockClient);
Expand Down
16 changes: 0 additions & 16 deletions test/components/views/context_menus/MessageContextMenu-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,6 @@ describe("MessageContextMenu", () => {
expect(screen.queryByRole("menuitem", { name: "Pin" })).toBeFalsy();
});

it("does not show pin option when pinning feature is disabled", () => {
const eventContent = createMessageEventContent("hello");
const pinnableEvent = new MatrixEvent({
type: EventType.RoomMessage,
content: eventContent,
room_id: roomId,
});

// disable pinning feature
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);

createMenu(pinnableEvent, { rightClick: true }, {}, undefined, room);

expect(screen.queryByRole("menuitem", { name: "Pin" })).toBeFalsy();
});

it("shows pin option when pinning feature is enabled", () => {
const eventContent = createMessageEventContent("hello");
const pinnableEvent = new MatrixEvent({
Expand Down
12 changes: 3 additions & 9 deletions test/components/views/right_panel/RoomSummaryCard-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,7 @@ describe("<RoomSummaryCard />", () => {
});

describe("pinning", () => {
it("renders pins options when pinning feature is enabled", () => {
mocked(settingsHooks.useFeatureEnabled).mockImplementation((feature) => feature === "feature_pinning");
it("renders pins options", () => {
const { getByText } = getComponent();

expect(getByText("Pinned messages")).toBeInTheDocument();
Expand Down Expand Up @@ -291,9 +290,7 @@ describe("<RoomSummaryCard />", () => {
describe("video rooms", () => {
it("does not render irrelevant options for element video room", () => {
jest.spyOn(room, "isElementVideoRoom").mockReturnValue(true);
mocked(settingsHooks.useFeatureEnabled).mockImplementation(
(feature) => feature === "feature_video_rooms" || feature === "feature_pinning",
);
mocked(settingsHooks.useFeatureEnabled).mockImplementation((feature) => feature === "feature_video_rooms");
const { queryByText } = getComponent();

// options not rendered
Expand All @@ -305,10 +302,7 @@ describe("<RoomSummaryCard />", () => {
it("does not render irrelevant options for element call room", () => {
jest.spyOn(room, "isCallRoom").mockReturnValue(true);
mocked(settingsHooks.useFeatureEnabled).mockImplementation(
(feature) =>
feature === "feature_element_call_video_rooms" ||
feature === "feature_video_rooms" ||
feature === "feature_pinning",
(feature) => feature === "feature_element_call_video_rooms" || feature === "feature_video_rooms",
);
const { queryByText } = getComponent();

Expand Down
Loading

0 comments on commit 5985277

Please sign in to comment.