chat input now always sits at the bottom of the chat; has a divider
This commit is contained in:
parent
c31712464b
commit
30f0d671af
5 changed files with 35 additions and 106 deletions
|
|
@ -1,12 +1,9 @@
|
||||||
import { Chat as ChatIcon, ChevronRight } from "@mui/icons-material";
|
import { Chat as ChatIcon } from "@mui/icons-material";
|
||||||
import { Box, Drawer, IconButton, Theme, Tooltip, Typography } from "@mui/material";
|
import { Box, IconButton, Theme, Tooltip } from "@mui/material";
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
import Chat from "chat/Chat";
|
|
||||||
import { ChatDrawer } from "chat/ChatDrawer";
|
import { ChatDrawer } from "chat/ChatDrawer";
|
||||||
import { useMobile } from "hooks";
|
|
||||||
import { Team, User } from "models";
|
import { Team, User } from "models";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { pond } from "protobuf-ts/pond";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { getSignatureAccentColour } from "services/whiteLabel";
|
import { getSignatureAccentColour } from "services/whiteLabel";
|
||||||
|
|
||||||
|
|
@ -33,18 +30,6 @@ const useStyles = makeStyles((theme: Theme) => ({
|
||||||
off: {
|
off: {
|
||||||
backgroundColor: "transparent"
|
backgroundColor: "transparent"
|
||||||
},
|
},
|
||||||
chatDrawer: {
|
|
||||||
padding: theme.spacing(1),
|
|
||||||
height: "100%",
|
|
||||||
minWidth: theme.spacing(54),
|
|
||||||
maxWidth: theme.spacing(54),
|
|
||||||
zIndex: 1000000000000
|
|
||||||
},
|
|
||||||
chatDrawerMobile: {
|
|
||||||
padding: theme.spacing(1),
|
|
||||||
height: "auto",
|
|
||||||
width: "100%"
|
|
||||||
},
|
|
||||||
drawerHeader: {
|
drawerHeader: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
|
|
@ -65,10 +50,7 @@ export default function HeaderButtons(props: Props) {
|
||||||
const {hasTeams, /*user,*/ team} = props
|
const {hasTeams, /*user,*/ team} = props
|
||||||
const [hasNewChats, setHasNewChats] = useState(false);
|
const [hasNewChats, setHasNewChats] = useState(false);
|
||||||
const [chatDrawerOpen, setChatDrawerOpen] = useState(false);
|
const [chatDrawerOpen, setChatDrawerOpen] = useState(false);
|
||||||
|
|
||||||
// const theme = useTheme();
|
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const isMobile = useMobile();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!team) return;
|
if (!team) return;
|
||||||
|
|
@ -109,7 +91,6 @@ export default function HeaderButtons(props: Props) {
|
||||||
width="8px"
|
width="8px"
|
||||||
height="8px"
|
height="8px"
|
||||||
borderRadius="50%"
|
borderRadius="50%"
|
||||||
// style={{ backgroundColor: theme.palette.primary.main }}
|
|
||||||
className={classes.on}
|
className={classes.on}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -126,74 +107,7 @@ export default function HeaderButtons(props: Props) {
|
||||||
onClose={() => setChatDrawerOpen(false)}
|
onClose={() => setChatDrawerOpen(false)}
|
||||||
team={team}
|
team={team}
|
||||||
/>
|
/>
|
||||||
// <Drawer
|
|
||||||
// anchor="right"
|
|
||||||
// open={chatDrawerOpen}
|
|
||||||
// sx={{ zIndex: 10000 }}
|
|
||||||
// onClose={() => setChatDrawerOpen(false)}
|
|
||||||
// style={{ height: "100%", maxWidth: "100%" }}
|
|
||||||
// title={team.settings.name ? team.settings.name + "Chat" : "Chat"}>
|
|
||||||
|
|
||||||
// <div className={isMobile ? classes.chatDrawerMobile : classes.chatDrawer}>
|
|
||||||
// <div className={classes.drawerHeader}>
|
|
||||||
// <IconButton onClick={() => setChatDrawerOpen(false)}>
|
|
||||||
// <ChevronRight />
|
|
||||||
// </IconButton>
|
|
||||||
// <Typography>{team.name()} Chat</Typography>
|
|
||||||
// </div>
|
|
||||||
// <Chat objectKey={team.settings.key} type={pond.NoteType.NOTE_TYPE_TEAM} />
|
|
||||||
// </div>
|
|
||||||
// </Drawer>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
// return (
|
|
||||||
// {user.settings?.notificationMethods?.includes(
|
|
||||||
// pond.NotificationMethod.NOTIFICATION_METHOD_APP
|
|
||||||
// ) && (
|
|
||||||
// <div style={{ position: "relative", marginLeft: theme.spacing(-1) }}>
|
|
||||||
// <Tooltip title="Notifications">
|
|
||||||
// <IconButton
|
|
||||||
// style={{ marginLeft: theme.spacing(1) }}
|
|
||||||
// onClick={() => {
|
|
||||||
// setNotificationDrawerOpen(true);
|
|
||||||
// }}>
|
|
||||||
// <Notifications />
|
|
||||||
// </IconButton>
|
|
||||||
// </Tooltip>
|
|
||||||
// {hasNewNotifications && (
|
|
||||||
// <Box
|
|
||||||
// width="8px"
|
|
||||||
// height="8px"
|
|
||||||
// borderRadius="50%"
|
|
||||||
// style={{ backgroundColor: theme.palette.primary.main }}
|
|
||||||
// className={classes.on}
|
|
||||||
// />
|
|
||||||
// )}
|
|
||||||
// </div>
|
|
||||||
// )}
|
|
||||||
// {team && team.settings && team.settings.key && (
|
|
||||||
// <Drawer
|
|
||||||
// anchor="right"
|
|
||||||
// open={chatDrawerOpen}
|
|
||||||
// onClose={() => setChatDrawerOpen(false)}
|
|
||||||
// style={{ height: "100%", maxWidth: "100%" }}
|
|
||||||
// title={team.settings.name ? team.settings.name + "Chat" : "Chat"}>
|
|
||||||
// <div className={isMobile ? classes.chatDrawerMobile : classes.chatDrawer}>
|
|
||||||
// <div className={classes.drawerHeader}>
|
|
||||||
// <IconButton onClick={() => setChatDrawerOpen(false)}>
|
|
||||||
// <ChevronRightIcon />
|
|
||||||
// </IconButton>
|
|
||||||
// <Typography>{team.name()} Chat</Typography>
|
|
||||||
// </div>
|
|
||||||
// <Chat objectKey={team.settings.key} type={pond.NoteType.NOTE_TYPE_TEAM} />
|
|
||||||
// </div>
|
|
||||||
// </Drawer>
|
|
||||||
// )}
|
|
||||||
// <NotificationDrawer
|
|
||||||
// setNotificationDrawerOpen={setNotificationDrawerOpen}
|
|
||||||
// notificationDrawerOpen={notificationDrawerOpen}
|
|
||||||
// />
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Box, CircularProgress } from "@mui/material";
|
import { Box, CircularProgress, Divider, Theme } from "@mui/material";
|
||||||
import { useGlobalState, useNoteAPI } from "providers";
|
import { useGlobalState, useNoteAPI } from "providers";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
@ -7,6 +7,18 @@ import ChatInput from "./ChatInput";
|
||||||
import ChatOutput from "./ChatOutput";
|
import ChatOutput from "./ChatOutput";
|
||||||
import { Note } from "models";
|
import { Note } from "models";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
import { makeStyles } from "@mui/styles";
|
||||||
|
|
||||||
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
|
return ({
|
||||||
|
chatContainer: {
|
||||||
|
height: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
objectKey: string;
|
objectKey: string;
|
||||||
|
|
@ -21,6 +33,7 @@ export default function Chat(props: Props) {
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [totalMessages, setTotalMessages] = useState(0);
|
const [totalMessages, setTotalMessages] = useState(0);
|
||||||
const [{ user }] = useGlobalState();
|
const [{ user }] = useGlobalState();
|
||||||
|
const classes = useStyles()
|
||||||
|
|
||||||
const loadChats = () => {
|
const loadChats = () => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
@ -79,8 +92,7 @@ export default function Chat(props: Props) {
|
||||||
<CircularProgress />
|
<CircularProgress />
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<div style={{ maxHeight: "100%", display: "flex", flexDirection: "column-reverse" }}>
|
<Box className={classes.chatContainer}>
|
||||||
<ChatInput newNoteMethod={showNewNotes} objectKey={objectKey} type={type} />
|
|
||||||
<ChatOutput
|
<ChatOutput
|
||||||
totalMessages={totalMessages}
|
totalMessages={totalMessages}
|
||||||
// attachmentMap={attachmentMap}
|
// attachmentMap={attachmentMap}
|
||||||
|
|
@ -88,7 +100,11 @@ export default function Chat(props: Props) {
|
||||||
removeNoteMethod={removeNote}
|
removeNoteMethod={removeNote}
|
||||||
loadMore={loadMore}
|
loadMore={loadMore}
|
||||||
/>
|
/>
|
||||||
</div>
|
<Box style={{bottom: 0}}>
|
||||||
|
<Divider/>
|
||||||
|
<ChatInput newNoteMethod={showNewNotes} objectKey={objectKey} type={type} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { makeStyles } from "@mui/styles";
|
||||||
import { useMobile } from "hooks";
|
import { useMobile } from "hooks";
|
||||||
import { Team } from "models";
|
import { Team } from "models";
|
||||||
import Chat from "./Chat";
|
import Chat from "./Chat";
|
||||||
|
import { pond } from "protobuf-ts/pond";
|
||||||
|
|
||||||
const useStyles = makeStyles((theme: Theme) => {
|
const useStyles = makeStyles((theme: Theme) => {
|
||||||
return ({
|
return ({
|
||||||
|
|
@ -57,7 +58,7 @@ export function ChatDrawer(props: Props) {
|
||||||
<Typography>{team.name()} Chat</Typography>
|
<Typography>{team.name()} Chat</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<Box className={classes.chatContainer}>
|
<Box className={classes.chatContainer}>
|
||||||
<Chat objectKey={team.settings.key}/>
|
<Chat objectKey={team.settings.key} type={pond.NoteType.NOTE_TYPE_TEAM}/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { Team, teamScope, User } from "models";
|
||||||
// import { useSnackbar } from "notistack";
|
// import { useSnackbar } from "notistack";
|
||||||
import PageContainer from "pages/PageContainer";
|
import PageContainer from "pages/PageContainer";
|
||||||
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||||
|
import { pond } from "protobuf-ts/pond";
|
||||||
import { useSnackbar, useTeamAPI, useUserAPI } from "providers";
|
import { useSnackbar, useTeamAPI, useUserAPI } from "providers";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
|
|
@ -225,7 +226,7 @@ export default function TeamPage() {
|
||||||
<Grid2 container spacing={1}>
|
<Grid2 container spacing={1}>
|
||||||
<Grid2 size={{ xs: 12, sm: 6 }}>
|
<Grid2 size={{ xs: 12, sm: 6 }}>
|
||||||
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
<Card className={ isMobile ? classes.cardMobile : classes.card }>
|
||||||
<Chat objectKey={team.key()} />
|
<Chat objectKey={team.key()} type={pond.NoteType.NOTE_TYPE_TEAM}/>
|
||||||
</Card>
|
</Card>
|
||||||
</Grid2>
|
</Grid2>
|
||||||
<Grid2 size={{ xs: 12, sm: 6 }}>
|
<Grid2 size={{ xs: 12, sm: 6 }}>
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,12 @@ import {
|
||||||
Typography
|
Typography
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { green, red } from "@mui/material/colors";
|
import { green, red } from "@mui/material/colors";
|
||||||
// import { Theme } from "@mui/material/styles/createMuiTheme";
|
|
||||||
import {
|
import {
|
||||||
Add as AddIcon,
|
Add as AddIcon,
|
||||||
Link as LinkIcon,
|
Link as LinkIcon,
|
||||||
LinkOff,
|
LinkOff,
|
||||||
RemoveCircle as RemoveCircleIcon
|
RemoveCircle as RemoveCircleIcon
|
||||||
} from "@mui/icons-material";
|
} from "@mui/icons-material";
|
||||||
// import { MobileDateTimePicker } from "@mui/utils/pi";
|
|
||||||
import { MobileDateTimePicker } from '@mui/x-date-pickers';
|
import { MobileDateTimePicker } from '@mui/x-date-pickers';
|
||||||
import ResponsiveDialog from "common/ResponsiveDialog";
|
import ResponsiveDialog from "common/ResponsiveDialog";
|
||||||
import { usePermissionAPI, usePrevious, useSnackbar } from "hooks";
|
import { usePermissionAPI, usePrevious, useSnackbar } from "hooks";
|
||||||
|
|
@ -41,7 +39,6 @@ import moment, { Moment } from "moment";
|
||||||
import { pond } from "protobuf-ts/pond";
|
import { pond } from "protobuf-ts/pond";
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { openSnackbar } from "providers/Snackbar";
|
import { openSnackbar } from "providers/Snackbar";
|
||||||
// import { Status } from "@sentry/react";
|
|
||||||
import { useBinAPI, useGateAPI } from "providers";
|
import { useBinAPI, useGateAPI } from "providers";
|
||||||
import { makeStyles } from "@mui/styles";
|
import { makeStyles } from "@mui/styles";
|
||||||
|
|
||||||
|
|
@ -131,7 +128,7 @@ export default function ShareObject(props: Props) {
|
||||||
resp.data.bins.forEach(bin => {
|
resp.data.bins.forEach(bin => {
|
||||||
if (bin.settings) {
|
if (bin.settings) {
|
||||||
let newScope = binScope(bin.settings?.key);
|
let newScope = binScope(bin.settings?.key);
|
||||||
permissionAPI.shareObject(newScope, email, sharedPermissions).catch(err => {
|
permissionAPI.shareObject(newScope, email, sharedPermissions).catch(_err => {
|
||||||
successBins = false;
|
successBins = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +158,7 @@ export default function ShareObject(props: Props) {
|
||||||
resp.data.gates.forEach(gate => {
|
resp.data.gates.forEach(gate => {
|
||||||
if (gate) {
|
if (gate) {
|
||||||
let newScope = { key: gate.key, kind: "gate" } as Scope;
|
let newScope = { key: gate.key, kind: "gate" } as Scope;
|
||||||
permissionAPI.shareObject(newScope, email, sharedPermissions).catch(err => {
|
permissionAPI.shareObject(newScope, email, sharedPermissions).catch(_err => {
|
||||||
successGates = false;
|
successGates = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +172,7 @@ export default function ShareObject(props: Props) {
|
||||||
}
|
}
|
||||||
closeAfterShare();
|
closeAfterShare();
|
||||||
})
|
})
|
||||||
.catch((err: any) => {
|
.catch((_err: any) => {
|
||||||
error("Unable to share " + label + " with " + email);
|
error("Unable to share " + label + " with " + email);
|
||||||
close();
|
close();
|
||||||
});
|
});
|
||||||
|
|
@ -192,7 +189,7 @@ export default function ShareObject(props: Props) {
|
||||||
);
|
);
|
||||||
setShareableLinks(rShareableLinks);
|
setShareableLinks(rShareableLinks);
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((_error: any) => {
|
||||||
setShareableLinks([]);
|
setShareableLinks([]);
|
||||||
console.log("Error occured while loading shareable links");
|
console.log("Error occured while loading shareable links");
|
||||||
})
|
})
|
||||||
|
|
@ -215,10 +212,10 @@ export default function ShareObject(props: Props) {
|
||||||
const expiration = isNewLinkInfinite ? getNeverExpires() : newLinkExpiration.toISOString();
|
const expiration = isNewLinkInfinite ? getNeverExpires() : newLinkExpiration.toISOString();
|
||||||
permissionAPI
|
permissionAPI
|
||||||
.addShareableLink(scope, expiration)
|
.addShareableLink(scope, expiration)
|
||||||
.then((response: any) => {
|
.then((_response: any) => {
|
||||||
loadShareableLinks();
|
loadShareableLinks();
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((_error: any) => {
|
||||||
console.log("Error occured while creating shareable link");
|
console.log("Error occured while creating shareable link");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -226,10 +223,10 @@ export default function ShareObject(props: Props) {
|
||||||
const revokeShareableLink = (code: string) => {
|
const revokeShareableLink = (code: string) => {
|
||||||
permissionAPI
|
permissionAPI
|
||||||
.removeShareableLink(scope, code)
|
.removeShareableLink(scope, code)
|
||||||
.then((response: any) => {
|
.then((_response: any) => {
|
||||||
loadShareableLinks();
|
loadShareableLinks();
|
||||||
})
|
})
|
||||||
.catch((error: any) => {
|
.catch((_error: any) => {
|
||||||
console.log("Error occured while removing the shareable link");
|
console.log("Error occured while removing the shareable link");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
@ -295,7 +292,7 @@ export default function ShareObject(props: Props) {
|
||||||
setSharedPermissions(updatedSharedPermissions);
|
setSharedPermissions(updatedSharedPermissions);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeTab = (event: any, newTab: number) => {
|
const changeTab = (_event: any, newTab: number) => {
|
||||||
setTab(newTab);
|
setTab(newTab);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue