100 lines
3.3 KiB
TypeScript
100 lines
3.3 KiB
TypeScript
/*
|
|
Copyright 2021 - 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 React, { useCallback, useContext, useEffect, useRef } from "react";
|
|
import { Room } from "matrix-js-sdk/src/models/room";
|
|
import classNames from "classnames";
|
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
|
|
|
import { linkifyElement } from "../../../HtmlUtils";
|
|
import { useTopic } from "../../../hooks/room/useTopic";
|
|
import useHover from "../../../hooks/useHover";
|
|
import Tooltip, { Alignment } from "./Tooltip";
|
|
import { _t } from "../../../languageHandler";
|
|
import dis from "../../../dispatcher/dispatcher";
|
|
import { Action } from "../../../dispatcher/actions";
|
|
import Modal from "../../../Modal";
|
|
import InfoDialog from "../dialogs/InfoDialog";
|
|
import { useDispatcher } from "../../../hooks/useDispatcher";
|
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
|
import AccessibleButton from "./AccessibleButton";
|
|
import { Linkify } from "./Linkify";
|
|
|
|
interface IProps extends React.HTMLProps<HTMLDivElement> {
|
|
room?: Room;
|
|
}
|
|
|
|
export default function RoomTopic({
|
|
room,
|
|
...props
|
|
}: IProps) {
|
|
const client = useContext(MatrixClientContext);
|
|
const ref = useRef<HTMLDivElement>();
|
|
const hovered = useHover(ref);
|
|
|
|
const topic = useTopic(room);
|
|
|
|
const onClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
|
|
props.onClick?.(e);
|
|
const target = e.target as HTMLElement;
|
|
if (target.tagName.toUpperCase() === "A") {
|
|
return;
|
|
}
|
|
|
|
dis.fire(Action.ShowRoomTopic);
|
|
}, [props]);
|
|
|
|
useDispatcher(dis, (payload) => {
|
|
if (payload.action === Action.ShowRoomTopic) {
|
|
const canSetTopic = room.currentState.maySendStateEvent(EventType.RoomTopic, client.getUserId());
|
|
|
|
const modal = Modal.createDialog(InfoDialog, {
|
|
title: room.name,
|
|
description: <div>
|
|
<Linkify as="p">{ topic }</Linkify>
|
|
{ canSetTopic && <AccessibleButton
|
|
kind="primary_outline"
|
|
onClick={() => {
|
|
modal.close();
|
|
dis.dispatch({ action: "open_room_settings" });
|
|
}}>
|
|
{ _t("Edit topic") }
|
|
</AccessibleButton> }
|
|
</div>,
|
|
hasCloseButton: true,
|
|
button: false,
|
|
});
|
|
}
|
|
});
|
|
|
|
useEffect(() => {
|
|
linkifyElement(ref.current);
|
|
}, [topic]);
|
|
|
|
const className = classNames(props.className, "mx_RoomTopic");
|
|
|
|
return <div {...props}
|
|
ref={ref}
|
|
onClick={onClick}
|
|
dir="auto"
|
|
className={className}
|
|
>
|
|
{ topic }
|
|
{ hovered && (
|
|
<Tooltip label={_t("Click to read topic")} alignment={Alignment.Bottom} />
|
|
) }
|
|
</div>;
|
|
}
|