mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-01-18 02:41:33 +00:00
124 lines
4.1 KiB
JavaScript
124 lines
4.1 KiB
JavaScript
import {
|
|
UserInputError
|
|
} from 'apollo-server'
|
|
import extractMentionedUsers from './notifications/extractMentionedUsers'
|
|
import extractHashtags from './hashtags/extractHashtags'
|
|
|
|
const notifyUsers = async (label, id, idsOfUsers, reason, context) => {
|
|
if (!idsOfUsers.length) return
|
|
|
|
// Done here, because Neode validation is not working.
|
|
const reasonsAllowed = ['mentioned_in_post', 'mentioned_in_comment', 'comment_on_your_post']
|
|
if (!(reasonsAllowed.includes(reason))) {
|
|
throw new UserInputError("Notification reason is not allowed!")
|
|
}
|
|
|
|
const session = context.driver.session()
|
|
const createdAt = new Date().toISOString()
|
|
const cypher = `
|
|
MATCH (source)
|
|
WHERE source.id = $id AND $label IN LABELS(source)
|
|
MATCH (source)<-[:WROTE]-(author: User)
|
|
MATCH (u: User)
|
|
WHERE u.id in $idsOfUsers
|
|
AND NOT (u)<-[:BLOCKED]-(author)
|
|
CREATE (n: Notification { id: apoc.create.uuid(), read: false, reason: $reason, createdAt: $createdAt })
|
|
MERGE (source)-[:NOTIFIED]->(n)-[:NOTIFIED]->(u)
|
|
`
|
|
await session.run(cypher, {
|
|
label,
|
|
id,
|
|
idsOfUsers,
|
|
reason,
|
|
createdAt,
|
|
})
|
|
session.close()
|
|
}
|
|
|
|
const updateHashtagsOfPost = async (postId, hashtags, context) => {
|
|
if (!hashtags.length) return
|
|
|
|
const session = context.driver.session()
|
|
// We need two Cypher statements, because the 'MATCH' in the 'cypherDeletePreviousRelations' statement
|
|
// functions as an 'if'. In case there is no previous relation, the rest of the commands are omitted
|
|
// and no new Hashtags and relations will be created.
|
|
const cypherDeletePreviousRelations = `
|
|
MATCH (p: Post { id: $postId })-[previousRelations: TAGGED]->(t: Tag)
|
|
DELETE previousRelations
|
|
RETURN p, t
|
|
`
|
|
const cypherCreateNewTagsAndRelations = `
|
|
MATCH (p: Post { id: $postId})
|
|
UNWIND $hashtags AS tagName
|
|
MERGE (t: Tag { id: tagName, name: tagName, disabled: false, deleted: false })
|
|
MERGE (p)-[:TAGGED]->(t)
|
|
RETURN p, t
|
|
`
|
|
await session.run(cypherDeletePreviousRelations, {
|
|
postId,
|
|
})
|
|
await session.run(cypherCreateNewTagsAndRelations, {
|
|
postId,
|
|
hashtags,
|
|
})
|
|
session.close()
|
|
}
|
|
|
|
const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo) => {
|
|
// extract user ids before xss-middleware removes classes via the following "resolve" call
|
|
const idsOfUsers = extractMentionedUsers(args.content)
|
|
// extract tag (hashtag) ids before xss-middleware removes classes via the following "resolve" call
|
|
const hashtags = extractHashtags(args.content)
|
|
|
|
// removes classes from the content
|
|
const post = await resolve(root, args, context, resolveInfo)
|
|
|
|
await notifyUsers('Post', post.id, idsOfUsers, 'mentioned_in_post', context)
|
|
await updateHashtagsOfPost(post.id, hashtags, context)
|
|
|
|
return post
|
|
}
|
|
|
|
const handleContentDataOfComment = async (resolve, root, args, context, resolveInfo) => {
|
|
// extract user ids before xss-middleware removes classes via the following "resolve" call
|
|
const idsOfUsers = extractMentionedUsers(args.content)
|
|
|
|
// removes classes from the content
|
|
const comment = await resolve(root, args, context, resolveInfo)
|
|
|
|
await notifyUsers('Comment', comment.id, idsOfUsers, 'mentioned_in_comment', context)
|
|
|
|
return comment
|
|
}
|
|
|
|
const handleCreateComment = async (resolve, root, args, context, resolveInfo) => {
|
|
// removes classes from the content
|
|
const comment = await handleContentDataOfComment(resolve, root, args, context, resolveInfo)
|
|
|
|
const session = context.driver.session()
|
|
const cypherFindUser = `
|
|
MATCH (user: User)-[:WROTE]->(:Post)<-[:COMMENTS]-(:Comment { id: $commentId })
|
|
RETURN user { .id }
|
|
`
|
|
const result = await session.run(cypherFindUser, {
|
|
commentId: comment.id,
|
|
})
|
|
session.close()
|
|
const [userWrotePost] = await result.records.map(record => {
|
|
return record.get('user')
|
|
})
|
|
if (context.user.id !== userWrotePost.id) {
|
|
await notifyUsers('Comment', comment.id, [userWrotePost.id], 'comment_on_your_post', context)
|
|
}
|
|
|
|
return comment
|
|
}
|
|
|
|
export default {
|
|
Mutation: {
|
|
CreatePost: handleContentDataOfPost,
|
|
UpdatePost: handleContentDataOfPost,
|
|
CreateComment: handleCreateComment,
|
|
UpdateComment: handleContentDataOfComment,
|
|
},
|
|
} |