Message.tsx

  1import React, { useState } from 'react';
  2
  3import IconButton from '@material-ui/core/IconButton';
  4import Paper from '@material-ui/core/Paper';
  5import Tooltip from '@material-ui/core/Tooltip/Tooltip';
  6import { makeStyles } from '@material-ui/core/styles';
  7import EditIcon from '@material-ui/icons/Edit';
  8
  9import Author, { Avatar } from 'src/components/Author';
 10import Content from 'src/components/Content';
 11import Date from 'src/components/Date';
 12import IfLoggedIn from 'src/components/IfLoggedIn/IfLoggedIn';
 13
 14import { BugFragment } from './Bug.generated';
 15import EditCommentForm from './EditCommentForm';
 16import EditHistoryMenu from './EditHistoryMenu';
 17import { AddCommentFragment } from './MessageCommentFragment.generated';
 18import { CreateFragment } from './MessageCreateFragment.generated';
 19
 20const useStyles = makeStyles((theme) => ({
 21  author: {
 22    fontWeight: 'bold',
 23  },
 24  container: {
 25    display: 'flex',
 26  },
 27  avatar: {
 28    marginTop: 2,
 29  },
 30  bubble: {
 31    flex: 1,
 32    marginLeft: theme.spacing(1),
 33    minWidth: 0,
 34  },
 35  header: {
 36    ...theme.typography.body1,
 37    padding: '0.5rem 1rem',
 38    borderBottom: `1px solid ${theme.palette.divider}`,
 39    display: 'flex',
 40    borderTopRightRadius: theme.shape.borderRadius,
 41    borderTopLeftRadius: theme.shape.borderRadius,
 42    backgroundColor: theme.palette.info.main,
 43    color: theme.palette.info.contrastText,
 44  },
 45  title: {
 46    flex: 1,
 47  },
 48  tag: {
 49    ...theme.typography.button,
 50    color: '#888',
 51    border: '#ddd solid 1px',
 52    padding: '0 0.5rem',
 53    fontSize: '0.75rem',
 54    borderRadius: 2,
 55    marginLeft: '0.5rem',
 56  },
 57  body: {
 58    ...theme.typography.body2,
 59    padding: '0.5rem',
 60  },
 61  headerActions2: {},
 62  headerActions: {
 63    color: theme.palette.info.contrastText,
 64    padding: '0rem',
 65    marginLeft: theme.spacing(1),
 66    fontSize: '0.75rem',
 67    '&:hover': {
 68      backgroundColor: 'inherit',
 69    },
 70  },
 71}));
 72
 73type Props = {
 74  bug: BugFragment;
 75  op: AddCommentFragment | CreateFragment;
 76};
 77
 78function Message({ bug, op }: Props) {
 79  const classes = useStyles();
 80  const [editMode, switchToEditMode] = useState(false);
 81  const [comment, setComment] = useState(op);
 82
 83  const editComment = (id: String) => {
 84    switchToEditMode(true);
 85  };
 86
 87  function readMessageView() {
 88    return (
 89      <Paper elevation={1} className={classes.bubble}>
 90        <header className={classes.header}>
 91          <div className={classes.title}>
 92            <Author className={classes.author} author={comment.author} />
 93            <span> commented </span>
 94            <Date date={comment.createdAt} />
 95          </div>
 96          {comment.edited && (
 97            <EditHistoryMenu
 98              iconBtnProps={{ className: classes.headerActions }}
 99              bugId={bug.id}
100              commentId={comment.id}
101            />
102          )}
103          <IfLoggedIn>
104            {() => (
105              <Tooltip title="Edit Message" placement="top" arrow={true}>
106                <IconButton
107                  disableRipple
108                  className={classes.headerActions}
109                  aria-label="edit message"
110                  onClick={() => editComment(comment.id)}
111                >
112                  <EditIcon />
113                </IconButton>
114              </Tooltip>
115            )}
116          </IfLoggedIn>
117        </header>
118        <section className={classes.body}>
119          <Content markdown={comment.message} />
120        </section>
121      </Paper>
122    );
123  }
124
125  function editMessageView() {
126    const cancelEdition = () => {
127      switchToEditMode(false);
128    };
129
130    const onPostSubmit = (comment: AddCommentFragment | CreateFragment) => {
131      setComment(comment);
132      switchToEditMode(false);
133    };
134
135    return (
136      <div className={classes.bubble}>
137        <EditCommentForm
138          bug={bug}
139          onCancelClick={cancelEdition}
140          onPostSubmit={onPostSubmit}
141          comment={comment}
142        />
143      </div>
144    );
145  }
146
147  return (
148    <article className={classes.container}>
149      <Avatar author={comment.author} className={classes.avatar} />
150      {editMode ? editMessageView() : readMessageView()}
151    </article>
152  );
153}
154
155export default Message;