Skip to content

Commit

Permalink
refactor: split item panel
Browse files Browse the repository at this point in the history
  • Loading branch information
pyphilia committed Aug 12, 2021
1 parent e9f219d commit d0abdce
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 174 deletions.
50 changes: 50 additions & 0 deletions src/components/common/Chatbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Typography } from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import GraaspChatbox from '@graasp/chatbox';
import { MUTATION_KEYS } from '@graasp/query-client';
import { Map } from 'immutable';
import { Loader } from '@graasp/ui';
import { hooks, useMutation } from '../../config/queryClient';
import { HEADER_HEIGHT } from '../../config/constants';

const { useItemChat, useCurrentMember } = hooks;

const Chatbox = ({ item }) => {
const { t } = useTranslation();
const { data: chat, isLoading: isChatLoading } = useItemChat(item.get('id'));
const { data: currentMember, isLoadingCurrentMember } = useCurrentMember();
const { mutate: sendMessage } = useMutation(
MUTATION_KEYS.POST_ITEM_CHAT_MESSAGE,
);

const renderChatbox = () => {
if (isChatLoading || isLoadingCurrentMember) {
return <Loader />;
}

return (
<GraaspChatbox
currentMember={currentMember}
chatId={item.get('id')}
messages={chat?.get('messages')}
height={window.innerHeight - HEADER_HEIGHT * 2}
sendMessageFunction={sendMessage}
/>
);
};

return (
<>
<Typography variant="h5">{t('Comments')}</Typography>
{renderChatbox()}
</>
);
};

Chatbox.propTypes = {
item: PropTypes.instanceOf(Map).isRequired,
};

export default Chatbox;
3 changes: 3 additions & 0 deletions src/components/context/LayoutContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const LayoutContextProvider = ({ children }) => {
const [isItemMetadataMenuOpen, setIsItemMetadataMenuOpen] = useState(
isItemPanelOpen,
);
const [isChatboxMenuOpen, setIsChatboxMenuOpen] = useState(false);

return (
<LayoutContext.Provider
Expand All @@ -40,6 +41,8 @@ const LayoutContextProvider = ({ children }) => {
setIsItemSettingsOpen,
isItemMetadataMenuOpen,
setIsItemMetadataMenuOpen,
isChatboxMenuOpen,
setIsChatboxMenuOpen,
}}
>
{children}
Expand Down
35 changes: 27 additions & 8 deletions src/components/item/ItemMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import ItemHeader from './header/ItemHeader';
import ItemPanel from './ItemPanel';
import { ITEM_MAIN_CLASS } from '../../config/selectors';
import { LayoutContext } from '../context/LayoutContext';
import Chatbox from '../common/Chatbox';
import ItemMetadataContent from './ItemMetadataContent';

const useStyles = makeStyles((theme) => ({
root: {},
menuButton: {},
hide: {
display: 'none',
},
Expand Down Expand Up @@ -49,23 +49,42 @@ const useStyles = makeStyles((theme) => ({

const ItemMain = ({ id, children, item }) => {
const classes = useStyles();
const { isItemMetadataMenuOpen, setIsItemMetadataMenuOpen } = useContext(
LayoutContext,
);
const {
isItemMetadataMenuOpen,
setIsItemMetadataMenuOpen,
isChatboxMenuOpen,
setIsChatboxMenuOpen,
} = useContext(LayoutContext);

const handleToggleMetadataMenu = () => {
setIsItemMetadataMenuOpen(!isItemMetadataMenuOpen);
setIsChatboxMenuOpen(false);
};
const handleToggleChatboxMenu = () => {
setIsChatboxMenuOpen(!isChatboxMenuOpen);
setIsItemMetadataMenuOpen(false);
};

return (
<div id={id} className={ITEM_MAIN_CLASS}>
<ItemPanel item={item} open={isItemMetadataMenuOpen} />
{isChatboxMenuOpen && (
<ItemPanel open={isChatboxMenuOpen}>
<Chatbox item={item} />
</ItemPanel>
)}
<ItemPanel open={isItemMetadataMenuOpen}>
<ItemMetadataContent item={item} />
</ItemPanel>

<div
className={clsx(classes.root, classes.content, {
[classes.contentShift]: isItemMetadataMenuOpen,
[classes.contentShift]: isItemMetadataMenuOpen || isChatboxMenuOpen,
})}
>
<ItemHeader onClick={handleToggleMetadataMenu} />
<ItemHeader
onClickMetadata={handleToggleMetadataMenu}
onClickChatbox={handleToggleChatboxMenu}
/>

{children}
</div>
Expand Down
101 changes: 101 additions & 0 deletions src/components/item/ItemMetadataContent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import PropTypes from 'prop-types';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import { useTranslation } from 'react-i18next';
import TableRow from '@material-ui/core/TableRow';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import { formatDate } from '../../utils/date';
import { hooks } from '../../config/queryClient';
import { getFileExtra, getS3FileExtra } from '../../utils/itemExtra';
import { ITEM_PANEL_TABLE_ID } from '../../config/selectors';
import { ITEM_KEYS, ITEM_TYPES } from '../../enums';

const { useMember } = hooks;

const useStyles = makeStyles((theme) => ({
table: {
padding: theme.spacing(2),
},
extra: {
wordBreak: 'break-all',
},
name: {
wordBreak: 'break-word',
},
}));

const ItemMetadataContent = ({ item }) => {
const { t } = useTranslation();

const classes = useStyles();

const { data: creator } = useMember(item.get('creator'));

let type = null;
let size = null;
if (item.get(ITEM_KEYS.TYPE) === ITEM_TYPES.S3_FILE) {
const extra = getS3FileExtra(item.get('extra'));
({ contenttype: type, size } = extra);
} else if (item.get(ITEM_KEYS.TYPE) === ITEM_TYPES.FILE) {
const extra = getFileExtra(item.get('extra'));
({ mimetype: type, size } = extra);
} else {
type = item.get(ITEM_KEYS.TYPE);
}

return (
<>
<Typography variant="h5">{item.get(ITEM_KEYS.NAME)}</Typography>
<TableContainer className={classes.table}>
<Table
id={ITEM_PANEL_TABLE_ID}
size="small"
aria-label="item panel table"
>
<TableBody>
<TableRow>
<TableCell component="th" scope="row">
{t('Type')}
</TableCell>
<TableCell align="right">{type}</TableCell>
</TableRow>
{size && (
<TableRow>
<TableCell component="th" scope="row">
{t('Size')}
</TableCell>
<TableCell align="right">{size}</TableCell>
</TableRow>
)}
<TableRow>
<TableCell align="left">{t('Creator')}</TableCell>
<TableCell align="right">{creator?.get('name')}</TableCell>
</TableRow>
<TableRow>
<TableCell align="left">{t('Created At')}</TableCell>
<TableCell align="right">
{formatDate(item.get('createdAt'))}
</TableCell>
</TableRow>
<TableRow>
<TableCell align="left">{t('Updated At')}</TableCell>
<TableCell align="right">
{formatDate(item.get('updatedAt'))}
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</>
);
};

ItemMetadataContent.propTypes = {
item: PropTypes.instanceOf(Map).isRequired,
};

export default ItemMetadataContent;
Loading

0 comments on commit d0abdce

Please sign in to comment.