element-web/src/components/views/right_panel/WidgetCard.tsx

164 lines
5.2 KiB
TypeScript
Raw Normal View History

2020-09-08 10:48:03 +03:00
/*
Copyright 2020 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 React, {useContext, useEffect} from "react";
import {Room} from "matrix-js-sdk/src/models/room";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import BaseCard from "./BaseCard";
import WidgetUtils from "../../../utils/WidgetUtils";
import AccessibleButton from "../elements/AccessibleButton";
import AppTile from "../elements/AppTile";
import {_t} from "../../../languageHandler";
import {useWidgets} from "./RoomSummaryCard";
import {RightPanelPhases} from "../../../stores/RightPanelStorePhases";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import {SetRightPanelPhasePayload} from "../../../dispatcher/payloads/SetRightPanelPhasePayload";
import {Action} from "../../../dispatcher/actions";
2020-09-08 12:19:51 +03:00
import WidgetStore from "../../../stores/WidgetStore";
import {ChevronFace, ContextMenuButton, useContextMenu} from "../../structures/ContextMenu";
2020-09-08 14:01:44 +03:00
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import classNames from "classnames";
import RoomWidgetContextMenu from "../context_menus/RoomWidgetContextMenu";
2020-09-08 10:48:03 +03:00
interface IProps {
room: Room;
widgetId: string;
onClose(): void;
}
const WidgetCard: React.FC<IProps> = ({ room, widgetId, onClose }) => {
const cli = useContext(MatrixClientContext);
const apps = useWidgets(room);
const app = apps.find(a => a.id === widgetId);
const isPinned = app && WidgetStore.instance.isPinned(app.id);
2020-09-08 12:19:51 +03:00
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu();
2020-09-08 10:48:03 +03:00
useEffect(() => {
if (!app || isPinned) {
2020-09-08 18:27:09 +03:00
// stop showing this card
defaultDispatcher.dispatch<SetRightPanelPhasePayload>({
action: Action.SetRightPanelPhase,
phase: RightPanelPhases.RoomSummary,
});
2020-09-08 10:48:03 +03:00
}
}, [app, isPinned]);
// Don't render anything as we are about to transition
if (!app || isPinned) return null;
const header = <React.Fragment>
<h2>{ WidgetUtils.getWidgetName(app) }</h2>
</React.Fragment>;
2020-09-08 12:19:51 +03:00
const canModify = WidgetUtils.canUserModifyWidgets(room.roomId);
let contextMenu;
if (menuDisplayed) {
const rect = handle.current.getBoundingClientRect();
contextMenu = (
<RoomWidgetContextMenu
2020-09-08 12:19:51 +03:00
chevronFace={ChevronFace.None}
right={window.innerWidth - rect.right}
bottom={window.innerHeight - rect.top}
onFinished={closeMenu}
app={app}
/>
2020-09-08 12:19:51 +03:00
);
}
2020-09-08 10:48:03 +03:00
const onPinClick = () => {
WidgetStore.instance.pinWidget(app.id);
};
const onEditClick = () => {
WidgetUtils.editWidget(room, app);
};
2020-09-08 14:01:44 +03:00
let editButton;
if (canModify) {
editButton = <AccessibleButton kind="secondary" onClick={onEditClick}>
2020-09-08 10:48:03 +03:00
{ _t("Edit") }
2020-09-08 14:01:44 +03:00
</AccessibleButton>;
}
const pinButtonClasses = canModify ? "" : "mx_WidgetCard_widePinButton";
let pinButton;
if (WidgetStore.instance.canPin(app.id)) {
pinButton = <AccessibleButton
kind="secondary"
onClick={onPinClick}
className={pinButtonClasses}
>
2020-09-08 12:19:51 +03:00
{ _t("Pin to room") }
2020-09-08 14:01:44 +03:00
</AccessibleButton>;
} else {
pinButton = <AccessibleTooltipButton
title={_t("You can only pin 2 widgets at a time")}
2020-09-08 14:01:44 +03:00
tooltipClassName="mx_WidgetCard_maxPinnedTooltip"
kind="secondary"
className={pinButtonClasses}
disabled
>
{ _t("Pin to room") }
</AccessibleTooltipButton>;
}
const footer = <React.Fragment>
{ editButton }
{ pinButton }
2020-09-08 12:19:51 +03:00
<ContextMenuButton
kind="secondary"
2020-09-09 14:50:48 +03:00
className="mx_WidgetCard_optionsButton"
2020-09-08 12:19:51 +03:00
inputRef={handle}
onClick={openMenu}
isExpanded={menuDisplayed}
label={_t("Options")}
2020-09-09 14:50:48 +03:00
/>
2020-09-08 12:19:51 +03:00
{ contextMenu }
2020-09-08 10:48:03 +03:00
</React.Fragment>;
return <BaseCard
header={header}
footer={footer}
2020-09-08 14:01:44 +03:00
className={classNames("mx_WidgetCard", {
mx_WidgetCard_noEdit: !canModify,
})}
2020-09-08 10:48:03 +03:00
onClose={onClose}
previousPhase={RightPanelPhases.RoomSummary}
withoutScrollContainer
>
<AppTile
app={app}
fullWidth
show
showMenubar={false}
room={room}
userId={cli.getUserId()}
creatorUserId={app.creatorUserId}
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
waitForIframeLoad={app.waitForIframeLoad}
whitelistCapabilities={WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, room.roomId)}
/>
</BaseCard>;
};
export default WidgetCard;