Path: blob/master/src/packages/frontend/chat/chat-indicator.tsx
1496 views
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45// TODO: for a frame tree it really only makes sense for this button6// to always show the chat. For sagews and old stuff it should hide7// and show it. But it's very hard to know from here which doc type8// this is... so for now it still sort of toggles. For now things9// do work properly via a hack in close_chat in project_actions.1011import { filename_extension } from "@cocalc/util/misc";12import { Button, Tooltip } from "antd";13import { debounce } from "lodash";14import { useMemo } from "react";15import { FormattedMessage, useIntl } from "react-intl";16import { UsersViewing } from "@cocalc/frontend/account/avatar/users-viewing";17import { redux, useTypedRedux } from "@cocalc/frontend/app-framework";18import { HiddenXS } from "@cocalc/frontend/components";19import { Icon } from "@cocalc/frontend/components/icon";20import track from "@cocalc/frontend/user-tracking";21import { labels } from "../i18n";2223export type ChatState =24| "" // not opened (also undefined counts as not open)25| "internal" // chat is open and managed internally (via frame tree)26| "external" // chat is open and managed externally (e.g., legacy sage worksheet)27| "pending"; // chat should be opened when the file itself is actually initialized.2829const CHAT_INDICATOR_STYLE: React.CSSProperties = {30fontSize: "15pt",31paddingTop: "2px",32cursor: "pointer",33background: "#e8e8e8",34borderTop: "2px solid lightgrey",35} as const;3637const USERS_VIEWING_STYLE: React.CSSProperties = {38maxWidth: "120px",39marginRight: "5px",40} as const;4142interface Props {43project_id: string;44path: string;45chatState?: ChatState;46}4748export function ChatIndicator({ project_id, path, chatState }: Props) {49const style: React.CSSProperties = {50...CHAT_INDICATOR_STYLE,51...{ display: "flex" },52};5354return (55<div style={style}>56<UsersViewing57project_id={project_id}58path={path}59style={USERS_VIEWING_STYLE}60/>61<ChatButton project_id={project_id} path={path} chatState={chatState} />62</div>63);64}6566function ChatButton({ project_id, path, chatState }) {67const intl = useIntl();6869const toggleChat = debounce(70() => {71const actions = redux.getProjectActions(project_id);72if (chatState) {73track("close-chat", { project_id, path, how: "chat-button" });74actions.close_chat({ path });75} else {76track("open-chat", { project_id, path, how: "chat-button" });77actions.open_chat({ path });78}79},801000,81{ leading: true },82);83const fileUse = useTypedRedux("file_use", "file_use");84const isNewChat = useMemo(85() =>86!!redux.getStore("file_use")?.get_file_info(project_id, path)87?.is_unseenchat,88[fileUse, project_id, path],89);9091if (filename_extension(path) === "sage-chat") {92// Special case: do not show side chat for chatrooms93return null;94}9596return (97<Tooltip98title={99<span>100<Icon name="comment" style={{ marginRight: "5px" }} />101<FormattedMessage102id="chat.chat-indicator.tooltip"103defaultMessage={"Hide or Show Document Chat"}104/>105</span>106}107placement={"leftTop"}108mouseEnterDelay={0.5}109>110<Button111type="text"112danger={isNewChat}113className={isNewChat ? "smc-chat-notification" : undefined}114onClick={toggleChat}115style={{ background: chatState ? "white" : undefined }}116>117<Icon name="comment" />118<HiddenXS>119<span style={{ marginLeft: "5px" }}>120{intl.formatMessage(labels.chat)}121</span>122</HiddenXS>123</Button>124</Tooltip>125);126}127128129