diff --git a/backend/src/middleware/handleHtmlContent/handleContentData.js b/backend/src/middleware/handleHtmlContent/handleContentData.js
new file mode 100644
index 000000000..53a6b65fb
--- /dev/null
+++ b/backend/src/middleware/handleHtmlContent/handleContentData.js
@@ -0,0 +1,77 @@
+import extractMentionedUsers from './notifications/extractMentionedUsers'
+import extractHashtags from './hashtags/extractHashtags'
+
+const notify = async (resolve, root, args, context, resolveInfo) => {
+ // extract user ids before xss-middleware removes link classes
+ const ids = extractMentionedUsers(args.content)
+
+ console.log('ids: ', ids)
+
+ const post = await resolve(root, args, context, resolveInfo)
+
+ const session = context.driver.session()
+ const {
+ id: postId
+ } = post
+ const createdAt = new Date().toISOString()
+ const cypher = `
+ match(u:User) where u.id in $ids
+ match(p:Post) where p.id = $postId
+ create(n:Notification{id: apoc.create.uuid(), read: false, createdAt: $createdAt})
+ merge (n)-[:NOTIFIED]->(u)
+ merge (p)-[:NOTIFIED]->(n)
+ `
+ await session.run(cypher, {
+ ids,
+ createdAt,
+ postId
+ })
+ session.close()
+
+ return post
+}
+
+const updateHashtagsOfPost = async (postId, resolve, root, args, context, resolveInfo) => {
+ // extract tag (hashtag) ids before xss-middleware removes link classes
+ const hashtags = extractHashtags(args.content)
+
+ console.log('hashtags: ', hashtags)
+
+ // const post = await resolve(root, args, context, resolveInfo)
+
+ const session = context.driver.session()
+ // const {
+ // id: postId
+ // } = post
+ // const createdAt = new Date().toISOString()
+ const cypher = `
+ MATCH (p:Post { id: $postId })-[oldRelations: TAGGED]->(oldTags: Tag)
+ DELETE oldRelations
+ WITH p
+ UNWIND $hashtags AS tagName
+ MERGE (t: Tag { id: tagName, name: tagName })
+ MERGE (p)-[:TAGGED]->(t)
+ RETURN t
+ `
+ await session.run(cypher, {
+ postId,
+ hashtags
+ })
+ session.close()
+}
+
+const handleContentData = async (resolve, root, args, context, resolveInfo) => {
+ // extract user ids before xss-middleware removes link classes
+
+ const post = await notify(resolve, root, args, context, resolveInfo)
+ await updateHashtagsOfPost(post.id, resolve, root, args, context, resolveInfo)
+
+ return post
+}
+
+export default {
+ Mutation: {
+ CreatePost: handleContentData,
+ UpdatePost: handleContentData,
+ },
+}
\ No newline at end of file
diff --git a/backend/src/middleware/notifications/spec.js b/backend/src/middleware/handleHtmlContent/handleContentData.spec.js
similarity index 100%
rename from backend/src/middleware/notifications/spec.js
rename to backend/src/middleware/handleHtmlContent/handleContentData.spec.js
diff --git a/backend/src/middleware/handleHtmlContent/hashtags/extractHashtags.js b/backend/src/middleware/handleHtmlContent/hashtags/extractHashtags.js
new file mode 100644
index 000000000..194179b16
--- /dev/null
+++ b/backend/src/middleware/handleHtmlContent/hashtags/extractHashtags.js
@@ -0,0 +1,21 @@
+import cheerio from 'cheerio'
+const ID_REGEX = /\/search\/hashtag\/([\w\-.!~*'"(),]+)/g
+
+export default function (content) {
+ if (!content) return []
+ const $ = cheerio.load(content)
+ const urls = $('.hashtag')
+ .map((_, el) => {
+ return $(el).attr('href')
+ })
+ .get()
+ const hashtags = []
+ urls.forEach(url => {
+ console.log('url: ', url)
+ let match
+ while ((match = ID_REGEX.exec(url)) != null) {
+ hashtags.push(match[1])
+ }
+ })
+ return hashtags
+}
\ No newline at end of file
diff --git a/backend/src/middleware/notifications/extractIds/index.js b/backend/src/middleware/handleHtmlContent/notifications/extractMentionedUsers.js
similarity index 100%
rename from backend/src/middleware/notifications/extractIds/index.js
rename to backend/src/middleware/handleHtmlContent/notifications/extractMentionedUsers.js
diff --git a/backend/src/middleware/notifications/extractIds/spec.js b/backend/src/middleware/handleHtmlContent/notifications/extractMentionedUsers.spec.js
similarity index 98%
rename from backend/src/middleware/notifications/extractIds/spec.js
rename to backend/src/middleware/handleHtmlContent/notifications/extractMentionedUsers.spec.js
index 341c39cec..03de4f1bb 100644
--- a/backend/src/middleware/notifications/extractIds/spec.js
+++ b/backend/src/middleware/handleHtmlContent/notifications/extractMentionedUsers.spec.js
@@ -1,4 +1,4 @@
-import extractIds from '.'
+import extractIds from './extractMentionedUsers'
describe('extractIds', () => {
describe('content undefined', () => {
@@ -56,4 +56,4 @@ describe('extractIds', () => {
})
})
})
-})
+})
\ No newline at end of file
diff --git a/backend/src/middleware/index.js b/backend/src/middleware/index.js
index 9b85bd340..46470115f 100644
--- a/backend/src/middleware/index.js
+++ b/backend/src/middleware/index.js
@@ -11,7 +11,7 @@ import user from './userMiddleware'
import includedFields from './includedFieldsMiddleware'
import orderBy from './orderByMiddleware'
import validation from './validation'
-import notifications from './notifications'
+import handleContentData from './handleHtmlContent/handleContentData'
export default schema => {
const middlewares = {
@@ -22,7 +22,7 @@ export default schema => {
validation: validation,
sluggify: sluggify,
excerpt: excerpt,
- notifications: notifications,
+ handleContentData: handleContentData,
xss: xss,
softDelete: softDelete,
user: user,
@@ -38,7 +38,7 @@ export default schema => {
'validation',
'sluggify',
'excerpt',
- 'notifications',
+ 'handleContentData',
'xss',
'softDelete',
'user',
@@ -57,4 +57,4 @@ export default schema => {
}
return order.map(key => middlewares[key])
-}
+}
\ No newline at end of file
diff --git a/backend/src/middleware/notifications/index.js b/backend/src/middleware/notifications/index.js
deleted file mode 100644
index ca460a512..000000000
--- a/backend/src/middleware/notifications/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import extractIds from './extractIds'
-
-const notify = async (resolve, root, args, context, resolveInfo) => {
- // extract user ids before xss-middleware removes link classes
- const ids = extractIds(args.content)
-
- const post = await resolve(root, args, context, resolveInfo)
-
- const session = context.driver.session()
- const { id: postId } = post
- const createdAt = new Date().toISOString()
- const cypher = `
- match(u:User) where u.id in $ids
- match(p:Post) where p.id = $postId
- create(n:Notification{id: apoc.create.uuid(), read: false, createdAt: $createdAt})
- merge (n)-[:NOTIFIED]->(u)
- merge (p)-[:NOTIFIED]->(n)
- `
- await session.run(cypher, { ids, createdAt, postId })
- session.close()
-
- return post
-}
-
-export default {
- Mutation: {
- CreatePost: notify,
- UpdatePost: notify,
- },
-}
diff --git a/webapp/components/Editor/index.vue b/webapp/components/Editor/index.vue
index b7fa0263a..dbb30a42e 100644
--- a/webapp/components/Editor/index.vue
+++ b/webapp/components/Editor/index.vue
@@ -454,7 +454,7 @@ export default {
},
hashtag: {
// TODO: Fill up with input hashtag in search field
- url: `/search/hashtag:${item.name}`,
+ url: `/search/hashtag/${item.name}`,
label: item.name,
},
}