Merge pull request #824 from gotify/message-style
fix: less whitespace in message & add app name
This commit is contained in:
commit
7b9e8d9f83
|
|
@ -17,7 +17,7 @@ const DefaultPage: FC<React.PropsWithChildren<IProps>> = ({
|
||||||
<main style={{margin: '0 auto', maxWidth}}>
|
<main style={{margin: '0 auto', maxWidth}}>
|
||||||
<Grid container spacing={4}>
|
<Grid container spacing={4}>
|
||||||
<Grid size={{xs: 12}} style={{display: 'flex', flexWrap: 'wrap'}}>
|
<Grid size={{xs: 12}} style={{display: 'flex', flexWrap: 'wrap'}}>
|
||||||
<Typography variant="h4" style={{flex: 1}}>
|
<Typography variant="h4" style={{flex: 1, minWidth: 300}}>
|
||||||
{title}
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
{rightControl}
|
{rightControl}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,11 @@ const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
content: {
|
content: {
|
||||||
margin: '0 auto',
|
margin: '0 auto',
|
||||||
marginTop: 64,
|
marginTop: 64,
|
||||||
padding: theme.spacing(4),
|
padding: theme.spacing(3),
|
||||||
width: '100%',
|
width: '100%',
|
||||||
[theme.breakpoints.down('sm')]: {
|
[theme.breakpoints.down('sm')]: {
|
||||||
marginTop: 0,
|
marginTop: 0,
|
||||||
|
padding: theme.spacing(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,11 @@ const PREVIEW_LENGTH = 500;
|
||||||
const useStyles = makeStyles()((theme: Theme) => ({
|
const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
header: {
|
header: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexWrap: 'wrap',
|
width: '100%',
|
||||||
marginBottom: 0,
|
alignItems: 'start',
|
||||||
|
alignContent: 'center',
|
||||||
|
paddingBottom: 5,
|
||||||
|
wordBreak: 'break-all',
|
||||||
},
|
},
|
||||||
headerTitle: {
|
headerTitle: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
|
@ -29,17 +32,21 @@ const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
marginRight: -15,
|
marginRight: -15,
|
||||||
},
|
},
|
||||||
wrapperPadding: {
|
wrapperPadding: {
|
||||||
marginBottom: 12,
|
marginBottom: theme.spacing(2),
|
||||||
|
[theme.breakpoints.down('sm')]: {
|
||||||
|
marginBottom: theme.spacing(1),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
messageContentWrapper: {
|
messageContentWrapper: {
|
||||||
minWidth: 200,
|
minWidth: 200,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
marginRight: 15,
|
width: 50,
|
||||||
|
height: 50,
|
||||||
[theme.breakpoints.down('md')]: {
|
[theme.breakpoints.down('md')]: {
|
||||||
width: 32,
|
width: 30,
|
||||||
height: 32,
|
height: 30,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
date: {
|
date: {
|
||||||
|
|
@ -50,7 +57,9 @@ const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
imageWrapper: {
|
imageWrapper: {
|
||||||
display: 'flex',
|
marginRight: 15,
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
},
|
},
|
||||||
plainContent: {
|
plainContent: {
|
||||||
whiteSpace: 'pre-wrap',
|
whiteSpace: 'pre-wrap',
|
||||||
|
|
@ -64,6 +73,7 @@ const useStyles = makeStyles()((theme: Theme) => ({
|
||||||
},
|
},
|
||||||
'& p': {
|
'& p': {
|
||||||
margin: 0,
|
margin: 0,
|
||||||
|
wordBreak: 'break-word',
|
||||||
},
|
},
|
||||||
'& a': {
|
'& a': {
|
||||||
color: '#ff7f50',
|
color: '#ff7f50',
|
||||||
|
|
@ -121,7 +131,7 @@ const Message = ({
|
||||||
const {classes} = useStyles();
|
const {classes} = useStyles();
|
||||||
const [expanded, setExpanded] = React.useState(initialExpanded);
|
const [expanded, setExpanded] = React.useState(initialExpanded);
|
||||||
const [isOverflowing, setOverflowing] = React.useState(false);
|
const [isOverflowing, setOverflowing] = React.useState(false);
|
||||||
const dateWrapped = useMediaQuery(theme.breakpoints.down('md'));
|
const smallHeader = useMediaQuery(theme.breakpoints.down('md'));
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setOverflowing(!!previewRef && previewRef.scrollHeight > previewRef.clientHeight);
|
setOverflowing(!!previewRef && previewRef.scrollHeight > previewRef.clientHeight);
|
||||||
|
|
@ -150,48 +160,33 @@ const Message = ({
|
||||||
borderLeftWidth: 6,
|
borderLeftWidth: 6,
|
||||||
borderLeftStyle: 'solid',
|
borderLeftStyle: 'solid',
|
||||||
}}>
|
}}>
|
||||||
<div style={{display: 'flex', width: '100%'}}>
|
{smallHeader ? (
|
||||||
<div className={classes.imageWrapper}>
|
<HeaderSmall
|
||||||
{image !== null ? (
|
fDelete={fDelete}
|
||||||
<img
|
title={title}
|
||||||
src={config.get('url') + image}
|
appName={appName}
|
||||||
alt={`${appName} logo`}
|
image={image}
|
||||||
width="70"
|
date={date}
|
||||||
height="70"
|
/>
|
||||||
className={classes.image}
|
) : (
|
||||||
/>
|
<HeaderWide
|
||||||
) : null}
|
fDelete={fDelete}
|
||||||
</div>
|
title={title}
|
||||||
<div className={classes.messageContentWrapper}>
|
appName={appName}
|
||||||
<div className={classes.header}>
|
image={image}
|
||||||
<Typography className={`${classes.headerTitle} title`} variant="h5">
|
date={date}
|
||||||
{title}
|
/>
|
||||||
</Typography>
|
)}
|
||||||
<Typography variant="body1" className={classes.date}>
|
|
||||||
<TimeAgo
|
|
||||||
date={date}
|
|
||||||
formatter={makeIntlFormatter({
|
|
||||||
style: dateWrapped ? 'long' : 'narrow',
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</Typography>
|
|
||||||
<IconButton
|
|
||||||
onClick={fDelete}
|
|
||||||
className={`${classes.trash} delete`}
|
|
||||||
size="large">
|
|
||||||
<Delete />
|
|
||||||
</IconButton>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Typography
|
<div className={classes.messageContentWrapper}>
|
||||||
component="div"
|
<Typography
|
||||||
ref={setPreviewRef}
|
component="div"
|
||||||
className={`${classes.content} content ${
|
ref={setPreviewRef}
|
||||||
isOverflowing && expanded ? 'expanded' : ''
|
className={`${classes.content} content ${
|
||||||
}`}>
|
isOverflowing && expanded ? 'expanded' : ''
|
||||||
{renderContent()}
|
}`}>
|
||||||
</Typography>
|
{renderContent()}
|
||||||
</div>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
{isOverflowing && (
|
{isOverflowing && (
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -210,4 +205,91 @@ const Message = ({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const HeaderWide = ({
|
||||||
|
appName,
|
||||||
|
image,
|
||||||
|
date,
|
||||||
|
fDelete,
|
||||||
|
title,
|
||||||
|
}: Pick<IProps, 'appName' | 'image' | 'fDelete' | 'date' | 'title'>) => {
|
||||||
|
const {classes} = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.header}>
|
||||||
|
<div className={classes.imageWrapper}>
|
||||||
|
{image !== null ? (
|
||||||
|
<img
|
||||||
|
src={config.get('url') + image}
|
||||||
|
alt={`${appName} logo`}
|
||||||
|
width="50"
|
||||||
|
height="50"
|
||||||
|
className={classes.image}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
<div className={classes.headerTitle}>
|
||||||
|
<Typography className="title" variant="h5" lineHeight={1.2}>
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle1" fontSize={12} style={{opacity: 0.7}}>
|
||||||
|
{appName}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<Typography variant="body1" className={classes.date}>
|
||||||
|
<TimeAgo date={date} formatter={makeIntlFormatter({style: 'narrow'})} />
|
||||||
|
</Typography>
|
||||||
|
<IconButton
|
||||||
|
onClick={fDelete}
|
||||||
|
style={{padding: 14}}
|
||||||
|
className={`${classes.trash} delete`}
|
||||||
|
size="large">
|
||||||
|
<Delete />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
const HeaderSmall = ({
|
||||||
|
appName,
|
||||||
|
image,
|
||||||
|
date,
|
||||||
|
fDelete,
|
||||||
|
title,
|
||||||
|
}: Pick<IProps, 'appName' | 'image' | 'fDelete' | 'date' | 'title'>) => {
|
||||||
|
const {classes} = useStyles();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.header}>
|
||||||
|
<div className={classes.headerTitle}>
|
||||||
|
<Typography className="title" variant="h5" lineHeight={1.2}>
|
||||||
|
{title}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle1" fontSize={12} style={{opacity: 0.7}}>
|
||||||
|
{appName}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1" className={classes.date}>
|
||||||
|
<TimeAgo date={date} formatter={makeIntlFormatter({style: 'long'})} />
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div style={{display: 'flex', alignItems: 'end', flexDirection: 'column'}}>
|
||||||
|
<IconButton
|
||||||
|
onClick={fDelete}
|
||||||
|
style={{padding: 14}}
|
||||||
|
className={`${classes.trash} delete`}
|
||||||
|
size="large">
|
||||||
|
<Delete />
|
||||||
|
</IconButton>
|
||||||
|
<div style={{width: 30, height: 30}}>
|
||||||
|
{image !== null ? (
|
||||||
|
<img
|
||||||
|
src={config.get('url') + image}
|
||||||
|
alt={`${appName} logo`}
|
||||||
|
className={classes.image}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Message;
|
export default Message;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue