Remove feature_favourite_messages
as it is has been abandoned for now (#11097)
* Remove `feature_favourite_messages` as it is has been abandoned for now * i18n * Fix test * Remove unused css
This commit is contained in:
parent
386a459b9f
commit
cb2b1718ff
7 changed files with 3 additions and 219 deletions
|
@ -21,7 +21,6 @@ limitations under the License.
|
|||
--MessageActionBar-item-hover-background: $panel-actions;
|
||||
--MessageActionBar-item-hover-borderRadius: 6px;
|
||||
--MessageActionBar-item-hover-zIndex: 1;
|
||||
--MessageActionBar-star-button-color: #ffa534;
|
||||
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
|
@ -118,10 +117,6 @@ limitations under the License.
|
|||
color: $primary-content;
|
||||
}
|
||||
|
||||
&.mx_MessageActionBar_favouriteButton_fillstar {
|
||||
color: var(--MessageActionBar-star-button-color);
|
||||
}
|
||||
|
||||
&.mx_MessageActionBar_downloadButton {
|
||||
--MessageActionBar-icon-size: 14px;
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import { Icon as EmojiIcon } from "../../../../res/img/element-icons/room/messag
|
|||
import { Icon as ResendIcon } from "../../../../res/img/element-icons/retry.svg";
|
||||
import { Icon as ThreadIcon } from "../../../../res/img/element-icons/message/thread.svg";
|
||||
import { Icon as TrashcanIcon } from "../../../../res/img/element-icons/trashcan.svg";
|
||||
import { Icon as StarIcon } from "../../../../res/img/element-icons/room/message-bar/star.svg";
|
||||
import { Icon as ReplyIcon } from "../../../../res/img/element-icons/room/message-bar/reply.svg";
|
||||
import { Icon as ExpandMessageIcon } from "../../../../res/img/element-icons/expand-message.svg";
|
||||
import { Icon as CollapseMessageIcon } from "../../../../res/img/element-icons/collapse-message.svg";
|
||||
|
@ -45,7 +44,6 @@ import Resend from "../../../Resend";
|
|||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
import { MediaEventHelper } from "../../../utils/MediaEventHelper";
|
||||
import DownloadActionButton from "./DownloadActionButton";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||
import ReplyChain from "../elements/ReplyChain";
|
||||
import ReactionPicker from "../emojipicker/ReactionPicker";
|
||||
|
@ -55,7 +53,6 @@ import { Key } from "../../../Keyboard";
|
|||
import { ALTERNATE_KEY_NAME } from "../../../accessibility/KeyboardShortcuts";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { ShowThreadPayload } from "../../../dispatcher/payloads/ShowThreadPayload";
|
||||
import useFavouriteMessages from "../../../hooks/useFavouriteMessages";
|
||||
import { GetRelationsForEvent } from "../rooms/EventTile";
|
||||
import { VoiceBroadcastInfoEventType } from "../../../voice-broadcast/types";
|
||||
import { ButtonEvent } from "../elements/AccessibleButton";
|
||||
|
@ -254,42 +251,6 @@ const ReplyInThreadButton: React.FC<IReplyInThreadButton> = ({ mxEvent }) => {
|
|||
);
|
||||
};
|
||||
|
||||
interface IFavouriteButtonProp {
|
||||
mxEvent: MatrixEvent;
|
||||
}
|
||||
|
||||
const FavouriteButton: React.FC<IFavouriteButtonProp> = ({ mxEvent }) => {
|
||||
const { isFavourite, toggleFavourite } = useFavouriteMessages();
|
||||
|
||||
const eventId = mxEvent.getId()!;
|
||||
const classes = classNames("mx_MessageActionBar_iconButton mx_MessageActionBar_favouriteButton", {
|
||||
mx_MessageActionBar_favouriteButton_fillstar: isFavourite(eventId),
|
||||
});
|
||||
|
||||
const onClick = useCallback(
|
||||
(e: ButtonEvent) => {
|
||||
// Don't open the regular browser or our context menu on right-click
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
toggleFavourite(eventId);
|
||||
},
|
||||
[toggleFavourite, eventId],
|
||||
);
|
||||
|
||||
return (
|
||||
<RovingAccessibleTooltipButton
|
||||
className={classes}
|
||||
title={_t("Favourite")}
|
||||
onClick={onClick}
|
||||
onContextMenu={onClick}
|
||||
data-testid={eventId}
|
||||
>
|
||||
<StarIcon />
|
||||
</RovingAccessibleTooltipButton>
|
||||
);
|
||||
};
|
||||
|
||||
interface IMessageActionBarProps {
|
||||
mxEvent: MatrixEvent;
|
||||
reactions?: Relations | null | undefined;
|
||||
|
@ -518,9 +479,6 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
|
|||
/>,
|
||||
);
|
||||
}
|
||||
if (SettingsStore.getValue("feature_favourite_messages")) {
|
||||
toolbarOpts.splice(-1, 0, <FavouriteButton key="favourite" mxEvent={this.props.mxEvent} />);
|
||||
}
|
||||
|
||||
// XXX: Assuming that the underlying tile will be a media event if it is eligible media.
|
||||
if (MediaEventHelper.isEligible(this.props.mxEvent)) {
|
||||
|
|
|
@ -78,7 +78,6 @@ interface IState {
|
|||
sublists: ITagMap;
|
||||
currentRoomId?: string;
|
||||
suggestedRooms: ISuggestedRoom[];
|
||||
feature_favourite_messages: boolean;
|
||||
}
|
||||
|
||||
export const TAG_ORDER: TagID[] = [
|
||||
|
@ -443,7 +442,6 @@ const TAG_AESTHETICS: TagAestheticsMap = {
|
|||
export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||
private dispatcherRef?: string;
|
||||
private treeRef = createRef<HTMLDivElement>();
|
||||
private favouriteMessageWatcher?: string;
|
||||
|
||||
public static contextType = MatrixClientContext;
|
||||
public context!: React.ContextType<typeof MatrixClientContext>;
|
||||
|
@ -454,7 +452,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
this.state = {
|
||||
sublists: {},
|
||||
suggestedRooms: SpaceStore.instance.suggestedRooms,
|
||||
feature_favourite_messages: SettingsStore.getValue("feature_favourite_messages"),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -463,20 +460,12 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
SdkContextClass.instance.roomViewStore.on(UPDATE_EVENT, this.onRoomViewStoreUpdate);
|
||||
SpaceStore.instance.on(UPDATE_SUGGESTED_ROOMS, this.updateSuggestedRooms);
|
||||
RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.updateLists);
|
||||
this.favouriteMessageWatcher = SettingsStore.watchSetting(
|
||||
"feature_favourite_messages",
|
||||
null,
|
||||
(...[, , , value]) => {
|
||||
this.setState({ feature_favourite_messages: value });
|
||||
},
|
||||
);
|
||||
this.updateLists(); // trigger the first update
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
SpaceStore.instance.off(UPDATE_SUGGESTED_ROOMS, this.updateSuggestedRooms);
|
||||
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.updateLists);
|
||||
if (this.favouriteMessageWatcher) SettingsStore.unwatchSetting(this.favouriteMessageWatcher);
|
||||
if (this.dispatcherRef) defaultDispatcher.unregister(this.dispatcherRef);
|
||||
SdkContextClass.instance.roomViewStore.off(UPDATE_EVENT, this.onRoomViewStoreUpdate);
|
||||
}
|
||||
|
@ -607,29 +596,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
);
|
||||
});
|
||||
}
|
||||
private renderFavoriteMessagesList(): ReactComponentElement<typeof ExtraTile>[] {
|
||||
const avatar = (
|
||||
<RoomAvatar
|
||||
oobData={{
|
||||
name: "Favourites",
|
||||
}}
|
||||
width={32}
|
||||
height={32}
|
||||
resizeMethod="crop"
|
||||
/>
|
||||
);
|
||||
|
||||
return [
|
||||
<ExtraTile
|
||||
isMinimized={this.props.isMinimized}
|
||||
isSelected={false}
|
||||
displayName="Favourite Messages"
|
||||
avatar={avatar}
|
||||
onClick={() => ""}
|
||||
key="favMessagesTile_key"
|
||||
/>,
|
||||
];
|
||||
}
|
||||
|
||||
private renderSublists(): React.ReactElement[] {
|
||||
// show a skeleton UI if the user is in no rooms and they are not filtering and have no suggested rooms
|
||||
|
@ -641,8 +607,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
let extraTiles: ReactComponentElement<typeof ExtraTile>[] | undefined;
|
||||
if (orderedTagId === DefaultTagID.Suggested) {
|
||||
extraTiles = this.renderSuggestedRooms();
|
||||
} else if (this.state.feature_favourite_messages && orderedTagId === DefaultTagID.SavedItems) {
|
||||
extraTiles = this.renderFavoriteMessagesList();
|
||||
}
|
||||
|
||||
const aesthetics = TAG_AESTHETICS[orderedTagId];
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
const favouriteMessageIds = JSON.parse(localStorage?.getItem("io_element_favouriteMessages") ?? "[]") as string[];
|
||||
|
||||
export default function useFavouriteMessages(): {
|
||||
toggleFavourite: (eventId: string) => void;
|
||||
isFavourite: (eventId: string) => boolean;
|
||||
} {
|
||||
const [, setX] = useState<string[]>();
|
||||
|
||||
//checks if an id already exist
|
||||
const isFavourite = (eventId: string): boolean => favouriteMessageIds.includes(eventId);
|
||||
|
||||
const toggleFavourite = (eventId: string): void => {
|
||||
isFavourite(eventId)
|
||||
? favouriteMessageIds.splice(favouriteMessageIds.indexOf(eventId), 1)
|
||||
: favouriteMessageIds.push(eventId);
|
||||
|
||||
//update the local storage
|
||||
localStorage.setItem("io_element_favouriteMessages", JSON.stringify(favouriteMessageIds));
|
||||
|
||||
// This forces a re-render to account for changes in appearance in real-time when the favourite button is toggled
|
||||
setX([]);
|
||||
};
|
||||
|
||||
return { isFavourite, toggleFavourite };
|
||||
}
|
|
@ -985,11 +985,10 @@
|
|||
"Temporary implementation. Locations persist in room history.": "Temporary implementation. Locations persist in room history.",
|
||||
"Dynamic room predecessors": "Dynamic room predecessors",
|
||||
"Enable MSC3946 (to support late-arriving room archives)": "Enable MSC3946 (to support late-arriving room archives)",
|
||||
"Favourite Messages": "Favourite Messages",
|
||||
"Under active development.": "Under active development.",
|
||||
"Force 15s voice broadcast chunk length": "Force 15s voice broadcast chunk length",
|
||||
"Enable new native OIDC flows (Under active development)": "Enable new native OIDC flows (Under active development)",
|
||||
"Rust cryptography implementation": "Rust cryptography implementation",
|
||||
"Under active development.": "Under active development.",
|
||||
"Font size": "Font size",
|
||||
"Use custom size": "Use custom size",
|
||||
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
|
||||
|
@ -2390,7 +2389,6 @@
|
|||
"React": "React",
|
||||
"Reply in thread": "Reply in thread",
|
||||
"Can't create a thread from an event with an existing relation": "Can't create a thread from an event with an existing relation",
|
||||
"Favourite": "Favourite",
|
||||
"Edit": "Edit",
|
||||
"Reply": "Reply",
|
||||
"Collapse quotes": "Collapse quotes",
|
||||
|
@ -3246,6 +3244,7 @@
|
|||
"Copy link": "Copy link",
|
||||
"Forget": "Forget",
|
||||
"Favourited": "Favourited",
|
||||
"Favourite": "Favourite",
|
||||
"Mentions only": "Mentions only",
|
||||
"Copy room link": "Copy room link",
|
||||
"Low Priority": "Low Priority",
|
||||
|
|
|
@ -426,14 +426,6 @@ export const SETTINGS: { [setting: string]: ISetting } = {
|
|||
shouldWarn: true,
|
||||
default: false,
|
||||
},
|
||||
"feature_favourite_messages": {
|
||||
isFeature: true,
|
||||
labsGroup: LabGroup.Messaging,
|
||||
supportedLevels: LEVELS_FEATURE,
|
||||
displayName: _td("Favourite Messages"),
|
||||
description: _td("Under active development."),
|
||||
default: false,
|
||||
},
|
||||
[Features.VoiceBroadcast]: {
|
||||
isFeature: true,
|
||||
labsGroup: LabGroup.Messaging,
|
||||
|
|
|
@ -433,88 +433,7 @@ describe("<MessageActionBar />", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("favourite button", () => {
|
||||
//for multiple event usecase
|
||||
const favButton = (evt: MatrixEvent) => {
|
||||
return getComponent({ mxEvent: evt }).getByTestId(evt.getId()!);
|
||||
};
|
||||
|
||||
describe("when favourite_messages feature is enabled", () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||
(setting) => setting === "feature_favourite_messages",
|
||||
);
|
||||
localStorageMock.clear();
|
||||
});
|
||||
|
||||
it("renders favourite button on own actionable event", () => {
|
||||
const { queryByLabelText } = getComponent({ mxEvent: alicesMessageEvent });
|
||||
expect(queryByLabelText("Favourite")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders favourite button on other actionable events", () => {
|
||||
const { queryByLabelText } = getComponent({ mxEvent: bobsMessageEvent });
|
||||
expect(queryByLabelText("Favourite")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("does not render Favourite button on non-actionable event", () => {
|
||||
//redacted event is not actionable
|
||||
const { queryByLabelText } = getComponent({ mxEvent: redactedEvent });
|
||||
expect(queryByLabelText("Favourite")).toBeFalsy();
|
||||
});
|
||||
|
||||
it("remembers favourited state of multiple events, and handles the localStorage of the events accordingly", () => {
|
||||
const alicesAction = favButton(alicesMessageEvent);
|
||||
const bobsAction = favButton(bobsMessageEvent);
|
||||
|
||||
//default state before being clicked
|
||||
expect(alicesAction.classList).not.toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(bobsAction.classList).not.toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(localStorageMock.getItem("io_element_favouriteMessages")).toBeNull();
|
||||
|
||||
//if only alice's event is fired
|
||||
fireEvent.click(alicesAction);
|
||||
|
||||
expect(alicesAction.classList).toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(bobsAction.classList).not.toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(
|
||||
"io_element_favouriteMessages",
|
||||
'["$alices_message"]',
|
||||
);
|
||||
|
||||
//when bob's event is fired,both should be styled and stored in localStorage
|
||||
fireEvent.click(bobsAction);
|
||||
|
||||
expect(alicesAction.classList).toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(bobsAction.classList).toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(localStorageMock.setItem).toHaveBeenCalledWith(
|
||||
"io_element_favouriteMessages",
|
||||
'["$alices_message","$bobs_message"]',
|
||||
);
|
||||
|
||||
//finally, at this point the localStorage should contain the two eventids
|
||||
expect(localStorageMock.getItem("io_element_favouriteMessages")).toEqual(
|
||||
'["$alices_message","$bobs_message"]',
|
||||
);
|
||||
|
||||
//if decided to unfavourite bob's event by clicking again
|
||||
fireEvent.click(bobsAction);
|
||||
expect(bobsAction.classList).not.toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(alicesAction.classList).toContain("mx_MessageActionBar_favouriteButton_fillstar");
|
||||
expect(localStorageMock.getItem("io_element_favouriteMessages")).toEqual('["$alices_message"]');
|
||||
});
|
||||
});
|
||||
|
||||
describe("when favourite_messages feature is disabled", () => {
|
||||
it("does not render", () => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
|
||||
const { queryByLabelText } = getComponent({ mxEvent: alicesMessageEvent });
|
||||
expect(queryByLabelText("Favourite")).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it.each([["React"], ["Reply"], ["Reply in thread"], ["Favourite"], ["Edit"]])(
|
||||
it.each([["React"], ["Reply"], ["Reply in thread"], ["Edit"]])(
|
||||
"does not show context menu when right-clicking",
|
||||
(buttonLabel: string) => {
|
||||
// For favourite button
|
||||
|
|
Loading…
Reference in a new issue