feat: comments post min delay
This commit is contained in:
parent
8a74904731
commit
e74605501f
@ -131,40 +131,51 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
onIntersect (entries, observer, isIntersecting) {
|
onIntersect (entries, observer, isIntersecting) {
|
||||||
if (isIntersecting) {
|
if (isIntersecting) {
|
||||||
this.fetch()
|
this.fetch(true)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async fetch () {
|
async fetch (silent = false) {
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
const results = await this.$apollo.query({
|
try {
|
||||||
query: gql`
|
const results = await this.$apollo.query({
|
||||||
query ($locale: String!, $path: String!) {
|
query: gql`
|
||||||
comments {
|
query ($locale: String!, $path: String!) {
|
||||||
list(locale: $locale, path: $path) {
|
comments {
|
||||||
id
|
list(locale: $locale, path: $path) {
|
||||||
render
|
id
|
||||||
authorName
|
render
|
||||||
createdAt
|
authorName
|
||||||
updatedAt
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
locale: this.$store.get('page/locale'),
|
||||||
|
path: this.$store.get('page/path')
|
||||||
|
},
|
||||||
|
fetchPolicy: 'network-only'
|
||||||
|
})
|
||||||
|
this.comments = _.get(results, 'data.comments.list', []).map(c => {
|
||||||
|
const nameParts = c.authorName.toUpperCase().split(' ')
|
||||||
|
let initials = _.head(nameParts).charAt(0)
|
||||||
|
if (nameParts.length > 1) {
|
||||||
|
initials += _.last(nameParts).charAt(0)
|
||||||
}
|
}
|
||||||
`,
|
c.initials = initials
|
||||||
variables: {
|
return c
|
||||||
locale: this.$store.get('page/locale'),
|
})
|
||||||
path: this.$store.get('page/path')
|
} catch (err) {
|
||||||
},
|
console.warn(err)
|
||||||
fetchPolicy: 'network-only'
|
if (!silent) {
|
||||||
})
|
this.$store.commit('showNotification', {
|
||||||
this.comments = _.get(results, 'data.comments.list', []).map(c => {
|
style: 'red',
|
||||||
const nameParts = c.authorName.toUpperCase().split(' ')
|
message: err.message,
|
||||||
let initials = _.head(nameParts).charAt(0)
|
icon: 'alert'
|
||||||
if (nameParts.length > 1) {
|
})
|
||||||
initials += _.last(nameParts).charAt(0)
|
|
||||||
}
|
}
|
||||||
c.initials = initials
|
}
|
||||||
return c
|
|
||||||
})
|
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
this.hasLoadedOnce = true
|
this.hasLoadedOnce = true
|
||||||
},
|
},
|
||||||
@ -214,59 +225,63 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await this.$apollo.mutate({
|
try {
|
||||||
mutation: gql`
|
const resp = await this.$apollo.mutate({
|
||||||
mutation (
|
mutation: gql`
|
||||||
$pageId: Int!
|
mutation (
|
||||||
$replyTo: Int
|
$pageId: Int!
|
||||||
$content: String!
|
$replyTo: Int
|
||||||
$guestName: String
|
$content: String!
|
||||||
$guestEmail: String
|
$guestName: String
|
||||||
) {
|
$guestEmail: String
|
||||||
comments {
|
) {
|
||||||
create (
|
comments {
|
||||||
pageId: $pageId
|
create (
|
||||||
replyTo: $replyTo
|
pageId: $pageId
|
||||||
content: $content
|
replyTo: $replyTo
|
||||||
guestName: $guestName
|
content: $content
|
||||||
guestEmail: $guestEmail
|
guestName: $guestName
|
||||||
) {
|
guestEmail: $guestEmail
|
||||||
responseResult {
|
) {
|
||||||
succeeded
|
responseResult {
|
||||||
errorCode
|
succeeded
|
||||||
slug
|
errorCode
|
||||||
message
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
|
id
|
||||||
}
|
}
|
||||||
id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
pageId: this.pageId,
|
||||||
|
replyTo: 0,
|
||||||
|
content: this.newcomment,
|
||||||
|
guestName: this.guestName,
|
||||||
|
guestEmail: this.guestEmail
|
||||||
}
|
}
|
||||||
`,
|
})
|
||||||
variables: {
|
|
||||||
pageId: this.pageId,
|
if (_.get(resp, 'data.comments.create.responseResult.succeeded', false)) {
|
||||||
replyTo: 0,
|
this.$store.commit('showNotification', {
|
||||||
content: this.newcomment,
|
style: 'success',
|
||||||
guestName: this.guestName,
|
message: 'New comment posted successfully.',
|
||||||
guestEmail: this.guestEmail
|
icon: 'check'
|
||||||
|
})
|
||||||
|
|
||||||
|
this.newcomment = ''
|
||||||
|
await this.fetch()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$vuetify.goTo(`#comment-post-id-${_.get(resp, 'data.comments.create.id', 0)}`, this.scrollOpts)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
throw new Error(_.get(resp, 'data.comments.create.responseResult.message', 'An unexpected error occured.'))
|
||||||
}
|
}
|
||||||
})
|
} catch (err) {
|
||||||
|
|
||||||
if (_.get(resp, 'data.comments.create.responseResult.succeeded', false)) {
|
|
||||||
this.$store.commit('showNotification', {
|
|
||||||
style: 'success',
|
|
||||||
message: 'New comment posted successfully.',
|
|
||||||
icon: 'check'
|
|
||||||
})
|
|
||||||
|
|
||||||
this.newcomment = ''
|
|
||||||
await this.fetch()
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$vuetify.goTo(`#comment-post-id-${_.get(resp, 'data.comments.create.id', 0)}`, this.scrollOpts)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.$store.commit('showNotification', {
|
this.$store.commit('showNotification', {
|
||||||
style: 'red',
|
style: 'red',
|
||||||
message: _.get(resp, 'data.comments.create.responseResult.message', 'An unexpected error occured.'),
|
message: err.message,
|
||||||
icon: 'alert'
|
icon: 'alert'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -286,42 +301,46 @@ export default {
|
|||||||
this.isBusy = true
|
this.isBusy = true
|
||||||
this.deleteCommentDialogShown = false
|
this.deleteCommentDialogShown = false
|
||||||
|
|
||||||
const resp = await this.$apollo.mutate({
|
try {
|
||||||
mutation: gql`
|
const resp = await this.$apollo.mutate({
|
||||||
mutation (
|
mutation: gql`
|
||||||
$id: Int!
|
mutation (
|
||||||
) {
|
$id: Int!
|
||||||
comments {
|
) {
|
||||||
delete (
|
comments {
|
||||||
id: $id
|
delete (
|
||||||
) {
|
id: $id
|
||||||
responseResult {
|
) {
|
||||||
succeeded
|
responseResult {
|
||||||
errorCode
|
succeeded
|
||||||
slug
|
errorCode
|
||||||
message
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
id: this.commentToDelete.id
|
||||||
}
|
}
|
||||||
`,
|
|
||||||
variables: {
|
|
||||||
id: this.commentToDelete.id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (_.get(resp, 'data.comments.delete.responseResult.succeeded', false)) {
|
|
||||||
this.$store.commit('showNotification', {
|
|
||||||
style: 'success',
|
|
||||||
message: 'Comment was deleted successfully.',
|
|
||||||
icon: 'check'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.comments = _.reject(this.comments, ['id', this.commentToDelete.id])
|
if (_.get(resp, 'data.comments.delete.responseResult.succeeded', false)) {
|
||||||
} else {
|
this.$store.commit('showNotification', {
|
||||||
|
style: 'success',
|
||||||
|
message: 'Comment was deleted successfully.',
|
||||||
|
icon: 'check'
|
||||||
|
})
|
||||||
|
|
||||||
|
this.comments = _.reject(this.comments, ['id', this.commentToDelete.id])
|
||||||
|
} else {
|
||||||
|
throw new Error(_.get(resp, 'data.comments.delete.responseResult.message', 'An unexpected error occured.'))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
this.$store.commit('showNotification', {
|
this.$store.commit('showNotification', {
|
||||||
style: 'red',
|
style: 'red',
|
||||||
message: _.get(resp, 'data.comments.delete.responseResult.message', 'An unexpected error occured.'),
|
message: err.message,
|
||||||
icon: 'alert'
|
icon: 'alert'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -362,6 +381,7 @@ export default {
|
|||||||
|
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
|
@ -42,7 +42,7 @@ type CommentMutation {
|
|||||||
content: String!
|
content: String!
|
||||||
guestName: String
|
guestName: String
|
||||||
guestEmail: String
|
guestEmail: String
|
||||||
): CommentCreateResponse @auth(requires: ["write:comments", "manage:system"])
|
): CommentCreateResponse @auth(requires: ["write:comments", "manage:system"]) @rateLimit(limit: 1, duration: 15)
|
||||||
|
|
||||||
update(
|
update(
|
||||||
id: Int!
|
id: Int!
|
||||||
|
@ -4,6 +4,7 @@ const { JSDOM } = require('jsdom')
|
|||||||
const createDOMPurify = require('dompurify')
|
const createDOMPurify = require('dompurify')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const { AkismetClient } = require('akismet-api')
|
const { AkismetClient } = require('akismet-api')
|
||||||
|
const moment = require('moment')
|
||||||
|
|
||||||
/* global WIKI */
|
/* global WIKI */
|
||||||
|
|
||||||
@ -106,6 +107,14 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -> Check for minimum delay between posts
|
||||||
|
if (WIKI.data.commentProvider.config.minDelay > 0) {
|
||||||
|
const lastComment = await WIKI.models.comments.query().select('updatedAt').findOne('authorId', user.id).orderBy('updatedAt', 'desc')
|
||||||
|
if (lastComment && moment().subtract(WIKI.data.commentProvider.config.minDelay, 'seconds').isBefore(lastComment.updatedAt)) {
|
||||||
|
throw new Error('Your administrator has set a time limit before you can post another comment. Try again later.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -> Save Comment to DB
|
// -> Save Comment to DB
|
||||||
const cm = await WIKI.models.comments.query().insert(newComment)
|
const cm = await WIKI.models.comments.query().insert(newComment)
|
||||||
|
|
||||||
|
@ -12,11 +12,12 @@ props:
|
|||||||
title: Akismet API Key
|
title: Akismet API Key
|
||||||
default: ''
|
default: ''
|
||||||
hint: 'Prevent spam by using the Akismet service. Enter your API key here to enable. Leave empty to disable.'
|
hint: 'Prevent spam by using the Akismet service. Enter your API key here to enable. Leave empty to disable.'
|
||||||
|
maxWidth: 650
|
||||||
order: 1
|
order: 1
|
||||||
minDelay:
|
minDelay:
|
||||||
type: Number
|
type: Number
|
||||||
title: Post delay
|
title: Post delay
|
||||||
default: 30
|
default: 30
|
||||||
hint: 'Minimum delay (in seconds) between comments per IP address.'
|
hint: 'Minimum delay (in seconds) between comments per account. Note that all guests are considered as a single account.'
|
||||||
maxWidth: 400
|
maxWidth: 400
|
||||||
order: 2
|
order: 2
|
||||||
|
Loading…
Reference in New Issue
Block a user