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