Update and expand ways to access pinned messages (#7906)

* Hide pinned messages header button when nothing is pinned

Signed-off-by: Robin Townsend <robin@robin.town>

* Add pinned messages option to room info panel

Signed-off-by: Robin Townsend <robin@robin.town>

* Add pinned messages option to room header menu

Signed-off-by: Robin Townsend <robin@robin.town>

* Make condition more concise

Signed-off-by: Robin Townsend <robin@robin.town>
This commit is contained in:
Robin 2022-02-28 09:52:16 -05:00 committed by GitHub
parent 33657947d3
commit 464bb727db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 1 deletions

View file

@ -251,6 +251,10 @@ limitations under the License.
mask-image: url('$(res)/img/element-icons/room/files.svg'); mask-image: url('$(res)/img/element-icons/room/files.svg');
} }
.mx_RoomSummaryCard_icon_pins::before {
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
}
.mx_RoomSummaryCard_icon_threads::before { .mx_RoomSummaryCard_icon_threads::before {
mask-image: url('$(res)/img/element-icons/message/thread.svg'); mask-image: url('$(res)/img/element-icons/message/thread.svg');
} }

View file

@ -213,6 +213,10 @@ limitations under the License.
mask-image: url('$(res)/img/element-icons/room/files.svg'); mask-image: url('$(res)/img/element-icons/room/files.svg');
} }
.mx_RoomTile_iconPins::before {
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
}
.mx_RoomTile_iconWidgets::before { .mx_RoomTile_iconWidgets::before {
mask-image: url('$(res)/img/element-icons/room/apps.svg'); mask-image: url('$(res)/img/element-icons/room/apps.svg');
} }

View file

@ -36,6 +36,8 @@ import { EchoChamber } from "../../../stores/local-echo/EchoChamber";
import { RoomNotifState } from "../../../RoomNotifs"; import { RoomNotifState } from "../../../RoomNotifs";
import Modal from "../../../Modal"; import Modal from "../../../Modal";
import ExportDialog from "../dialogs/ExportDialog"; import ExportDialog from "../dialogs/ExportDialog";
import { useSettingValue } from "../../../hooks/useSettings";
import { usePinnedEvents } from "../right_panel/PinnedMessagesCard";
import RoomViewStore from "../../../stores/RoomViewStore"; import RoomViewStore from "../../../stores/RoomViewStore";
import { RightPanelPhases } from '../../../stores/right-panel/RightPanelStorePhases'; import { RightPanelPhases } from '../../../stores/right-panel/RightPanelStorePhases';
import { ROOM_NOTIFICATIONS_TAB } from "../dialogs/RoomSettingsDialog"; import { ROOM_NOTIFICATIONS_TAB } from "../dialogs/RoomSettingsDialog";
@ -228,6 +230,29 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => {
/>; />;
} }
const pinningEnabled = useSettingValue("feature_pinning");
const pinCount = usePinnedEvents(pinningEnabled && room)?.length;
let pinsOption: JSX.Element;
if (pinningEnabled) {
pinsOption = <IconizedContextMenuOption
onClick={(ev: ButtonEvent) => {
ev.preventDefault();
ev.stopPropagation();
ensureViewingRoom(ev);
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.PinnedMessages }, false);
onFinished();
}}
label={_t("Pinned")}
iconClassName="mx_RoomTile_iconPins"
>
{ pinCount > 0 && <span className="mx_IconizedContextMenu_sublabel">
{ pinCount }
</span> }
</IconizedContextMenuOption>;
}
const onTagRoom = (ev: ButtonEvent, tagId: TagID) => { const onTagRoom = (ev: ButtonEvent, tagId: TagID) => {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
@ -278,6 +303,8 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => {
iconClassName="mx_RoomTile_iconFiles" iconClassName="mx_RoomTile_iconFiles"
/> />
{ pinsOption }
<IconizedContextMenuOption <IconizedContextMenuOption
onClick={(ev: ButtonEvent) => { onClick={(ev: ButtonEvent) => {
ev.preventDefault(); ev.preventDefault();

View file

@ -82,7 +82,7 @@ const PinnedMessagesHeaderButton = ({ room, isHighlighted, onClick }: IHeaderBut
const pinningEnabled = useSettingValue("feature_pinning"); const pinningEnabled = useSettingValue("feature_pinning");
const pinnedEvents = usePinnedEvents(pinningEnabled && room); const pinnedEvents = usePinnedEvents(pinningEnabled && room);
const readPinnedEvents = useReadPinnedEvents(pinningEnabled && room); const readPinnedEvents = useReadPinnedEvents(pinningEnabled && room);
if (!pinningEnabled) return null; if (!pinnedEvents?.length) return null;
let unreadIndicator; let unreadIndicator;
if (pinnedEvents.some(id => !readPinnedEvents.has(id))) { if (pinnedEvents.some(id => !readPinnedEvents.has(id))) {

View file

@ -42,6 +42,8 @@ import { UIFeature } from "../../../settings/UIFeature";
import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu"; import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu";
import WidgetContextMenu from "../context_menus/WidgetContextMenu"; import WidgetContextMenu from "../context_menus/WidgetContextMenu";
import { useRoomMemberCount } from "../../../hooks/useRoomMembers"; import { useRoomMemberCount } from "../../../hooks/useRoomMembers";
import { useSettingValue } from "../../../hooks/useSettings";
import { usePinnedEvents } from "./PinnedMessagesCard";
import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
import RoomName from "../elements/RoomName"; import RoomName from "../elements/RoomName";
import UIStore from "../../../stores/UIStore"; import UIStore from "../../../stores/UIStore";
@ -239,6 +241,10 @@ const onRoomFilesClick = () => {
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.FilePanel }, true); RightPanelStore.instance.pushCard({ phase: RightPanelPhases.FilePanel }, true);
}; };
const onRoomPinsClick = () => {
RightPanelStore.instance.pushCard({ phase: RightPanelPhases.PinnedMessages }, true);
};
const onRoomSettingsClick = (ev: ButtonEvent) => { const onRoomSettingsClick = (ev: ButtonEvent) => {
defaultDispatcher.dispatch({ action: "open_room_settings" }); defaultDispatcher.dispatch({ action: "open_room_settings" });
PosthogTrackers.trackInteraction("WebRightPanelRoomInfoSettingsButton", ev); PosthogTrackers.trackInteraction("WebRightPanelRoomInfoSettingsButton", ev);
@ -290,6 +296,8 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
</React.Fragment>; </React.Fragment>;
const memberCount = useRoomMemberCount(room); const memberCount = useRoomMemberCount(room);
const pinningEnabled = useSettingValue("feature_pinning");
const pinCount = usePinnedEvents(pinningEnabled && room)?.length;
return <BaseCard header={header} className="mx_RoomSummaryCard" onClose={onClose}> return <BaseCard header={header} className="mx_RoomSummaryCard" onClose={onClose}>
<Group title={_t("About")} className="mx_RoomSummaryCard_aboutGroup"> <Group title={_t("About")} className="mx_RoomSummaryCard_aboutGroup">
@ -302,6 +310,12 @@ const RoomSummaryCard: React.FC<IProps> = ({ room, onClose }) => {
<Button className="mx_RoomSummaryCard_icon_files" onClick={onRoomFilesClick}> <Button className="mx_RoomSummaryCard_icon_files" onClick={onRoomFilesClick}>
{ _t("Files") } { _t("Files") }
</Button> </Button>
{ pinningEnabled && <Button className="mx_RoomSummaryCard_icon_pins" onClick={onRoomPinsClick}>
{ _t("Pinned") }
{ pinCount > 0 && <span className="mx_BaseCard_Button_sublabel">
{ pinCount }
</span> }
</Button> }
<Button className="mx_RoomSummaryCard_icon_export" onClick={onRoomExportClick}> <Button className="mx_RoomSummaryCard_icon_export" onClick={onRoomExportClick}>
{ _t("Export chat") } { _t("Export chat") }
</Button> </Button>

View file

@ -1961,6 +1961,7 @@
"Not encrypted": "Not encrypted", "Not encrypted": "Not encrypted",
"About": "About", "About": "About",
"Files": "Files", "Files": "Files",
"Pinned": "Pinned",
"Export chat": "Export chat", "Export chat": "Export chat",
"Share room": "Share room", "Share room": "Share room",
"Room settings": "Room settings", "Room settings": "Room settings",