Allow markdown in messages (#180)

This commit is contained in:
Jannis Mattheis 2019-03-30 11:08:51 +01:00 committed by GitHub
parent 62854d8e11
commit e9bbe17fa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 7 deletions

View File

@ -2021,10 +2021,10 @@
"example": 25 "example": 25
}, },
"message": { "message": {
"description": "The actual message.", "description": "The message. Markdown (excluding html) is allowed.",
"type": "string", "type": "string",
"x-go-name": "Message", "x-go-name": "Message",
"example": "Backup was successfully finished." "example": "**Backup** was successfully finished."
}, },
"priority": { "priority": {
"description": "The priority of the message.", "description": "The priority of the message.",

View File

@ -33,10 +33,10 @@ type MessageExternal struct {
// required: true // required: true
// example: 5 // example: 5
ApplicationID uint `json:"appid"` ApplicationID uint `json:"appid"`
// The actual message. // The message. Markdown (excluding html) is allowed.
// //
// required: true // required: true
// example: Backup was successfully finished. // example: **Backup** was successfully finished.
Message string `form:"message" query:"message" json:"message" binding:"required"` Message string `form:"message" query:"message" json:"message" binding:"required"`
// The title of the message. // The title of the message.
// //

11
ui/package-lock.json generated
View File

@ -344,6 +344,12 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/remove-markdown": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@types/remove-markdown/-/remove-markdown-0.1.1.tgz",
"integrity": "sha512-SCYOFMHUqyiJU5M0V2gBB6UDdBhPwma34j0vYX0JgWaqp/74ila2Ops1jt5tB/C1UQXVXqK+is61884bITn3LQ==",
"dev": true
},
"@types/rimraf": { "@types/rimraf": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.2.tgz",
@ -11321,6 +11327,11 @@
"xtend": "^4.0.1" "xtend": "^4.0.1"
} }
}, },
"remove-markdown": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/remove-markdown/-/remove-markdown-0.3.0.tgz",
"integrity": "sha1-XktmdJOpNXlyjz1S7MHbnKUF3Jg="
},
"remove-trailing-separator": { "remove-trailing-separator": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",

View File

@ -23,6 +23,7 @@
"react-router": "^4.3.1", "react-router": "^4.3.1",
"react-router-dom": "^4.3.1", "react-router-dom": "^4.3.1",
"react-timeago": "^4.1.9", "react-timeago": "^4.1.9",
"remove-markdown": "^0.3.0",
"typeface-roboto": "0.0.54" "typeface-roboto": "0.0.54"
}, },
"scripts": { "scripts": {
@ -49,6 +50,7 @@
"@types/react-dom": "^16.0.7", "@types/react-dom": "^16.0.7",
"@types/react-infinite": "0.0.33", "@types/react-infinite": "0.0.33",
"@types/react-router-dom": "^4.3.0", "@types/react-router-dom": "^4.3.0",
"@types/remove-markdown": "^0.1.1",
"@types/rimraf": "^2.0.2", "@types/rimraf": "^2.0.2",
"get-port": "^4.0.0", "get-port": "^4.0.0",
"prettier": "^1.14.2", "prettier": "^1.14.2",

View File

@ -7,6 +7,7 @@ import TimeAgo from 'react-timeago';
import Container from '../common/Container'; import Container from '../common/Container';
import * as config from '../config'; import * as config from '../config';
import {StyleRulesCallback} from '@material-ui/core/styles/withStyles'; import {StyleRulesCallback} from '@material-ui/core/styles/withStyles';
import ReactMarkdown from 'react-markdown';
const styles: StyleRulesCallback = () => ({ const styles: StyleRulesCallback = () => ({
header: { header: {
@ -24,6 +25,7 @@ const styles: StyleRulesCallback = () => ({
}, },
messageContentWrapper: { messageContentWrapper: {
width: '100%', width: '100%',
maxWidth: 585,
}, },
image: { image: {
marginRight: 15, marginRight: 15,
@ -33,6 +35,15 @@ const styles: StyleRulesCallback = () => ({
}, },
content: { content: {
whiteSpace: 'pre-wrap', whiteSpace: 'pre-wrap',
'& p': {
margin: 0,
},
'& a': {
color: '#ff7f50',
},
'& pre': {
overflow: 'auto',
},
}, },
}); });
@ -81,8 +92,8 @@ class Message extends React.PureComponent<IProps & WithStyles<typeof styles>> {
<Delete /> <Delete />
</IconButton> </IconButton>
</div> </div>
<Typography component="p" className={`${classes.content} content`}> <Typography component="div" className={`${classes.content} content`}>
{content} <ReactMarkdown source={content} escapeHtml={true} />
</Typography> </Typography>
</div> </div>
</Container> </Container>

View File

@ -1,4 +1,5 @@
import Notify from 'notifyjs'; import Notify from 'notifyjs';
import removeMarkdown from 'remove-markdown';
export function requestPermission() { export function requestPermission() {
if (Notify.needsPermission && Notify.isSupported()) { if (Notify.needsPermission && Notify.isSupported()) {
@ -11,7 +12,7 @@ export function requestPermission() {
export function notifyNewMessage(msg: IMessage) { export function notifyNewMessage(msg: IMessage) {
const notify = new Notify(msg.title, { const notify = new Notify(msg.title, {
body: msg.message, body: removeMarkdown(msg.message),
icon: msg.image, icon: msg.image,
notifyClick: closeAndFocus, notifyClick: closeAndFocus,
notifyShow: closeAfterTimeout, notifyShow: closeAfterTimeout,