mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2026-04-02 23:55:28 +00:00
refactor(backend): remove content excerpt (#9441)
This commit is contained in:
parent
33f522ed16
commit
b088ec9e62
@ -199,9 +199,6 @@ Factory.define('post')
|
||||
// Convert false to null
|
||||
return pinned || null
|
||||
})
|
||||
.attr('contentExcerpt', ['contentExcerpt', 'content'], (contentExcerpt, content) => {
|
||||
return contentExcerpt || content
|
||||
})
|
||||
.attr('slug', ['slug', 'title'], (slug, title) => {
|
||||
return slug || slugify(title, { lower: true })
|
||||
})
|
||||
@ -294,9 +291,6 @@ Factory.define('comment')
|
||||
id: uuid,
|
||||
content: faker.lorem.sentence,
|
||||
})
|
||||
.attr('contentExcerpt', ['contentExcerpt', 'content'], (contentExcerpt, content) => {
|
||||
return contentExcerpt || content
|
||||
})
|
||||
.after(async (buildObject, options) => {
|
||||
const [comment, author, post] = await Promise.all([
|
||||
neode.create('Comment', buildObject),
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
||||
|
||||
import { getDriver } from '@db/neo4j'
|
||||
|
||||
export const description = 'Remove contentExcerpt property from Post and Comment nodes'
|
||||
|
||||
export async function up(_next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
await transaction.run(`
|
||||
MATCH (n)
|
||||
WHERE n:Post OR n:Comment
|
||||
REMOVE n.contentExcerpt
|
||||
`)
|
||||
await transaction.commit()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
await session.close()
|
||||
}
|
||||
}
|
||||
|
||||
export function down(_next) {
|
||||
throw new Error(
|
||||
'Irreversible migration: contentExcerpt was removed and cannot be restored without regenerating from content',
|
||||
)
|
||||
}
|
||||
@ -10,7 +10,6 @@ export default {
|
||||
default: () => new Date().toISOString(),
|
||||
},
|
||||
content: { type: 'string', disallow: [null], min: 3 },
|
||||
contentExcerpt: { type: 'string', allow: [null] },
|
||||
deleted: { type: 'boolean', default: false },
|
||||
disabled: { type: 'boolean', default: false },
|
||||
post: {
|
||||
|
||||
@ -19,7 +19,6 @@ export default {
|
||||
title: { type: 'string', disallow: [null], min: 3 },
|
||||
slug: { type: 'string', allow: [null], unique: 'true' },
|
||||
content: { type: 'string', disallow: [null], required: true, min: 3 },
|
||||
contentExcerpt: { type: 'string', allow: [null] },
|
||||
deleted: { type: 'boolean', default: false },
|
||||
disabled: { type: 'boolean', default: false },
|
||||
clickedCount: { type: 'int', default: 0 },
|
||||
|
||||
@ -2,7 +2,6 @@ import type { Integer, Node } from 'neo4j-driver'
|
||||
|
||||
export interface CommentDbProperties {
|
||||
content: string
|
||||
contentExcerpt: string
|
||||
createdAt: string
|
||||
deleted: boolean
|
||||
disabled: boolean
|
||||
|
||||
@ -3,7 +3,6 @@ import type { Integer, Node } from 'neo4j-driver'
|
||||
export interface PostDbProperties {
|
||||
clickedCount: number
|
||||
content: string
|
||||
contentExcerpt: string
|
||||
createdAt: string
|
||||
deleted: boolean
|
||||
disabled: boolean
|
||||
|
||||
@ -2,7 +2,6 @@ mutation DeleteComment($id: ID!) {
|
||||
DeleteComment(id: $id) {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
deleted
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ mutation DeletePost($id: ID!) {
|
||||
id
|
||||
deleted
|
||||
content
|
||||
contentExcerpt
|
||||
image {
|
||||
url
|
||||
}
|
||||
@ -11,7 +10,6 @@ mutation DeletePost($id: ID!) {
|
||||
id
|
||||
deleted
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ query Post($id: ID, $filter: _PostFilter, $first: Int, $offset: Int, $orderBy: [
|
||||
id
|
||||
title
|
||||
content
|
||||
contentExcerpt
|
||||
eventStart
|
||||
pinned
|
||||
createdAt
|
||||
|
||||
@ -7,19 +7,16 @@ mutation DeleteUser($id: ID!, $resource: [Deletable]) {
|
||||
contributions {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
deleted
|
||||
comments {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
deleted
|
||||
}
|
||||
}
|
||||
comments {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
deleted
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,6 @@ query User($id: ID, $name: String, $email: String) {
|
||||
comments {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
contributions {
|
||||
id
|
||||
@ -39,7 +38,6 @@ query User($id: ID, $name: String, $email: String) {
|
||||
url
|
||||
}
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
}
|
||||
isMuted
|
||||
|
||||
@ -30,7 +30,6 @@ query UserEmail($id: ID, $name: String, $email: String) {
|
||||
comments {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
contributions {
|
||||
id
|
||||
@ -40,7 +39,6 @@ query UserEmail($id: ID, $name: String, $email: String) {
|
||||
url
|
||||
}
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
}
|
||||
isMuted
|
||||
|
||||
@ -29,7 +29,6 @@ query UserEmailNotificationSettings($id: ID, $name: String, $email: String) {
|
||||
comments {
|
||||
id
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
contributions {
|
||||
id
|
||||
@ -39,7 +38,6 @@ query UserEmailNotificationSettings($id: ID, $name: String, $email: String) {
|
||||
url
|
||||
}
|
||||
content
|
||||
contentExcerpt
|
||||
}
|
||||
}
|
||||
isMuted
|
||||
|
||||
@ -240,7 +240,6 @@ describe('DeleteComment', () => {
|
||||
id: 'c456',
|
||||
deleted: true,
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
},
|
||||
}
|
||||
expect(data).toMatchObject(expected)
|
||||
|
||||
@ -83,7 +83,6 @@ export default {
|
||||
MATCH (comment:Comment {id: $commentId})
|
||||
SET comment.deleted = TRUE
|
||||
SET comment.content = 'UNAVAILABLE'
|
||||
SET comment.contentExcerpt = 'UNAVAILABLE'
|
||||
RETURN comment
|
||||
`,
|
||||
{ commentId: args.id },
|
||||
|
||||
@ -2000,7 +2000,6 @@ describe('DeletePost', () => {
|
||||
id: 'p4711',
|
||||
deleted: true,
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
image: null,
|
||||
comments: [],
|
||||
},
|
||||
@ -2015,7 +2014,6 @@ describe('DeletePost', () => {
|
||||
'comment',
|
||||
{
|
||||
content: 'to be deleted comment content',
|
||||
contentExcerpt: 'to be deleted comment content',
|
||||
},
|
||||
{
|
||||
postId: 'p4711',
|
||||
@ -2030,14 +2028,12 @@ describe('DeletePost', () => {
|
||||
id: 'p4711',
|
||||
deleted: true,
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
image: null,
|
||||
comments: [
|
||||
{
|
||||
deleted: true,
|
||||
// Should we black out the comment content in the database, too?
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -296,7 +296,6 @@ export default {
|
||||
OPTIONAL MATCH (post)<-[:COMMENTS]-(comment:Comment)
|
||||
SET post.deleted = TRUE
|
||||
SET post.content = 'UNAVAILABLE'
|
||||
SET post.contentExcerpt = 'UNAVAILABLE'
|
||||
SET post.title = 'UNAVAILABLE'
|
||||
SET comment.deleted = TRUE
|
||||
RETURN post {.*}
|
||||
|
||||
@ -354,13 +354,11 @@ describe('Delete a User as admin', () => {
|
||||
{
|
||||
id: 'p139',
|
||||
content: 'Post by user u343',
|
||||
contentExcerpt: 'Post by user u343',
|
||||
deleted: false,
|
||||
comments: [
|
||||
{
|
||||
id: 'c156',
|
||||
content: "A comment by someone else on user u343's post",
|
||||
contentExcerpt: "A comment by someone else on user u343's post",
|
||||
deleted: false,
|
||||
},
|
||||
],
|
||||
@ -370,7 +368,6 @@ describe('Delete a User as admin', () => {
|
||||
{
|
||||
id: 'c155',
|
||||
content: 'Comment by user u343',
|
||||
contentExcerpt: 'Comment by user u343',
|
||||
deleted: false,
|
||||
},
|
||||
],
|
||||
@ -400,13 +397,11 @@ describe('Delete a User as admin', () => {
|
||||
{
|
||||
id: 'p139',
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
deleted: true,
|
||||
comments: [
|
||||
{
|
||||
id: 'c156',
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
deleted: true,
|
||||
},
|
||||
],
|
||||
@ -416,7 +411,6 @@ describe('Delete a User as admin', () => {
|
||||
{
|
||||
id: 'c155',
|
||||
content: 'UNAVAILABLE',
|
||||
contentExcerpt: 'UNAVAILABLE',
|
||||
deleted: true,
|
||||
},
|
||||
],
|
||||
|
||||
@ -223,7 +223,6 @@ export default {
|
||||
OPTIONAL MATCH (resource)<-[:COMMENTS]-(comment:Comment)
|
||||
SET resource.deleted = true
|
||||
SET resource.content = 'UNAVAILABLE'
|
||||
SET resource.contentExcerpt = 'UNAVAILABLE'
|
||||
SET resource.language = 'UNAVAILABLE'
|
||||
SET resource.createdAt = 'UNAVAILABLE'
|
||||
SET resource.updatedAt = 'UNAVAILABLE'
|
||||
|
||||
@ -41,7 +41,6 @@ type Comment {
|
||||
activityId: String
|
||||
author: User @relation(name: "WROTE", direction: "IN")
|
||||
content: String!
|
||||
contentExcerpt: String
|
||||
post: Post @relation(name: "COMMENTS", direction: "OUT")
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
@ -81,7 +80,7 @@ type Query {
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
CreateComment(id: ID, postId: ID!, content: String!, contentExcerpt: String): Comment
|
||||
UpdateComment(id: ID!, content: String!, contentExcerpt: String): Comment
|
||||
CreateComment(id: ID, postId: ID!, content: String!): Comment
|
||||
UpdateComment(id: ID!, content: String!): Comment
|
||||
DeleteComment(id: ID!): Comment
|
||||
}
|
||||
|
||||
@ -129,7 +129,6 @@ type Post {
|
||||
title: String!
|
||||
slug: String!
|
||||
content: String!
|
||||
contentExcerpt: String
|
||||
image: Image @relation(name: "HERO_IMAGE", direction: "OUT")
|
||||
visibility: Visibility
|
||||
deleted: Boolean
|
||||
@ -230,7 +229,6 @@ type Mutation {
|
||||
visibility: Visibility
|
||||
language: String
|
||||
categoryIds: [ID]
|
||||
contentExcerpt: String
|
||||
groupId: ID
|
||||
postType: PostType = Article
|
||||
eventInput: _EventInput
|
||||
@ -240,7 +238,6 @@ type Mutation {
|
||||
title: String!
|
||||
slug: String
|
||||
content: String!
|
||||
contentExcerpt: String
|
||||
image: ImageInput
|
||||
visibility: Visibility
|
||||
language: String
|
||||
|
||||
@ -20,33 +20,9 @@ const updateGroup: IMiddlewareResolver = async (resolve, root, args, context, in
|
||||
return resolve(root, args, context, info)
|
||||
}
|
||||
|
||||
const createPost: IMiddlewareResolver = async (resolve, root, args, context, info) => {
|
||||
args.contentExcerpt = trunc(args.content, 120).html
|
||||
return resolve(root, args, context, info)
|
||||
}
|
||||
|
||||
const updatePost: IMiddlewareResolver = async (resolve, root, args, context, info) => {
|
||||
args.contentExcerpt = trunc(args.content, 120).html
|
||||
return resolve(root, args, context, info)
|
||||
}
|
||||
|
||||
const createComment: IMiddlewareResolver = async (resolve, root, args, context, info) => {
|
||||
args.contentExcerpt = trunc(args.content, 180).html
|
||||
return resolve(root, args, context, info)
|
||||
}
|
||||
|
||||
const updateComment: IMiddlewareResolver = async (resolve, root, args, context, info) => {
|
||||
args.contentExcerpt = trunc(args.content, 180).html
|
||||
return resolve(root, args, context, info)
|
||||
}
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
CreateGroup: createGroup,
|
||||
UpdateGroup: updateGroup,
|
||||
CreatePost: createPost,
|
||||
UpdatePost: updatePost,
|
||||
CreateComment: createComment,
|
||||
UpdateComment: updateComment,
|
||||
},
|
||||
}
|
||||
|
||||
@ -116,7 +116,6 @@ beforeAll(async () => {
|
||||
id: 'p2',
|
||||
title: 'Disabled post',
|
||||
content: 'This is an offensive post content',
|
||||
contentExcerpt: 'This is an offensive post content',
|
||||
deleted: false,
|
||||
},
|
||||
{
|
||||
@ -132,7 +131,6 @@ beforeAll(async () => {
|
||||
{
|
||||
id: 'c1',
|
||||
content: 'Disabled comment',
|
||||
contentExcerpt: 'Disabled comment',
|
||||
},
|
||||
{
|
||||
author: troll,
|
||||
@ -252,9 +250,6 @@ describe('softDeleteMiddleware', () => {
|
||||
it('displays content', () => {
|
||||
expect(subject.content).toEqual('This is an offensive post content')
|
||||
})
|
||||
it('displays contentExcerpt', () => {
|
||||
expect(subject.contentExcerpt).toEqual('This is an offensive post content')
|
||||
})
|
||||
it('displays image', () => {
|
||||
expect(subject.image).toEqual({
|
||||
url: expect.stringMatching('http://localhost/some/offensive/image.jpg'),
|
||||
@ -268,9 +263,6 @@ describe('softDeleteMiddleware', () => {
|
||||
it('displays content', () => {
|
||||
expect(subject.content).toEqual('Disabled comment')
|
||||
})
|
||||
it('displays contentExcerpt', () => {
|
||||
expect(subject.contentExcerpt).toEqual('Disabled comment')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -308,9 +300,6 @@ describe('softDeleteMiddleware', () => {
|
||||
it('obfuscates content', () => {
|
||||
expect(subject.content).toEqual('UNAVAILABLE')
|
||||
})
|
||||
it('obfuscates contentExcerpt', () => {
|
||||
expect(subject.contentExcerpt).toEqual('UNAVAILABLE')
|
||||
})
|
||||
it('obfuscates image', () => {
|
||||
expect(subject.image).toEqual(null)
|
||||
})
|
||||
@ -322,9 +311,6 @@ describe('softDeleteMiddleware', () => {
|
||||
it('obfuscates content', () => {
|
||||
expect(subject.content).toEqual('UNAVAILABLE')
|
||||
})
|
||||
it('obfuscates contentExcerpt', () => {
|
||||
expect(subject.contentExcerpt).toEqual('UNAVAILABLE')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -20,7 +20,6 @@ const setDefaultFilters: IMiddlewareResolver = async (resolve, root, args, conte
|
||||
const obfuscate: IMiddlewareResolver = async (resolve, root, args, context, info) => {
|
||||
if (root.deleted || (!isModerator(context) && root.disabled)) {
|
||||
root.content = 'UNAVAILABLE'
|
||||
root.contentExcerpt = 'UNAVAILABLE'
|
||||
root.title = 'UNAVAILABLE'
|
||||
root.slug = 'UNAVAILABLE'
|
||||
root.avatar = null
|
||||
|
||||
@ -41,7 +41,7 @@ const walkRecursive = (data, fields, fieldName, callback, _key?) => {
|
||||
// exclamation mark separates field names, that should not be sanitized
|
||||
const fields = [
|
||||
{ field: 'content', excludes: ['CreateMessage', 'Message'] },
|
||||
{ field: 'contentExcerpt' },
|
||||
|
||||
{ field: 'reasonDescription' },
|
||||
{ field: 'description', excludes: ['embed'] },
|
||||
{ field: 'descriptionExcerpt' },
|
||||
|
||||
@ -34,7 +34,7 @@ defineStep('I see all the reported posts including the one from above', () => {
|
||||
}
|
||||
... on Comment {
|
||||
id
|
||||
contentExcerpt
|
||||
content
|
||||
disabled
|
||||
deleted
|
||||
author {
|
||||
|
||||
@ -159,7 +159,7 @@ export default {
|
||||
titleIdent: 'delete.comment.title',
|
||||
messageIdent: 'delete.comment.message',
|
||||
messageParams: {
|
||||
name: this.$filters.truncate(this.comment.contentExcerpt, 30),
|
||||
name: this.$filters.truncate(this.$filters.removeHtml(this.comment.content), 30),
|
||||
},
|
||||
buttons: {
|
||||
confirm: {
|
||||
|
||||
@ -100,7 +100,7 @@ describe('NotificationsTable.vue', () => {
|
||||
it("renders the Post's content", () => {
|
||||
const boldTags = firstRowNotification.findAll('p')
|
||||
const content = boldTags.filter(
|
||||
(element) => element.text() === postNotification.from.contentExcerpt,
|
||||
(element) => element.text() === postNotification.from.content,
|
||||
)
|
||||
expect(content.exists()).toBe(true)
|
||||
})
|
||||
@ -133,12 +133,34 @@ describe('NotificationsTable.vue', () => {
|
||||
it("renders the Post's content", () => {
|
||||
const boldTags = secondRowNotification.findAll('p')
|
||||
const content = boldTags.filter(
|
||||
(element) => element.text() === commentNotification.from.contentExcerpt,
|
||||
(element) => element.text() === commentNotification.from.content,
|
||||
)
|
||||
expect(content.exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('fallback to descriptionExcerpt when content is empty', () => {
|
||||
it('renders descriptionExcerpt if content is missing', () => {
|
||||
const fallbackNotification = {
|
||||
read: false,
|
||||
reason: 'mentioned_in_post',
|
||||
from: {
|
||||
__typename: 'Post',
|
||||
id: 'post-fallback',
|
||||
title: 'fallback post',
|
||||
slug: 'fallback-post',
|
||||
content: '',
|
||||
descriptionExcerpt: 'fallback description text',
|
||||
author: { id: 'u1', slug: 'user', name: 'User' },
|
||||
},
|
||||
}
|
||||
propsData.notifications = [fallbackNotification]
|
||||
wrapper = Wrapper()
|
||||
const description = wrapper.find('.notification-description')
|
||||
expect(description.text()).toBe('fallback description text')
|
||||
})
|
||||
})
|
||||
|
||||
describe('unread status', () => {
|
||||
it('does not have class `notification-status`', () => {
|
||||
expect(wrapper.find('.notification-status').exists()).toBe(false)
|
||||
|
||||
@ -32,8 +32,6 @@ export const notifications = [
|
||||
deleted: false,
|
||||
content:
|
||||
'<p><a class="mention" href="/profile/u1" data-mention-id="u1" target="_blank">@peter-lustig</a> </p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra magna ac placerat. Tempor id eu nisl nunc mi ipsum faucibus vitae. Nibh praesent tristique magna sit amet purus gravida quis blandit. Magna eget est lorem ipsum dolor. In fermentum posuere urna nec. Eleifend donec pretium vulputate sapien nec sagittis aliquam. Augue interdum velit euismod in pellentesque. Id diam maecenas ultricies mi eget mauris pharetra. Donec pretium vulputate sapien nec. Dolor morbi non arcu risus quis varius quam quisque. Blandit turpis cursus in hac habitasse. Est ultricies integer quis auctor elit sed vulputate mi sit. Nunc consequat interdum varius sit amet mattis vulputate enim. Semper feugiat nibh sed pulvinar. Eget felis eget nunc lobortis mattis aliquam. Ultrices vitae auctor eu augue. Tellus molestie nunc non blandit massa enim nec dui. Pharetra massa massa ultricies mi quis hendrerit dolor. Nisl suscipit adipiscing bibendum est ultricies integer.</p>',
|
||||
contentExcerpt:
|
||||
'<p><a href="/profile/u1" target="_blank">@peter-lustig</a> </p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra …</p>',
|
||||
...post,
|
||||
author: user,
|
||||
},
|
||||
@ -53,8 +51,6 @@ export const notifications = [
|
||||
deleted: false,
|
||||
content:
|
||||
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra magna ac placerat. Tempor id eu nisl nunc mi ipsum faucibus vitae. Nibh praesent tristique magna sit amet purus gravida quis blandit. Magna eget est lorem ipsum dolor. In fermentum posuere urna nec. Eleifend donec pretium vulputate sapien nec sagittis aliquam. Augue interdum velit euismod in pellentesque. Id diam maecenas ultricies mi eget mauris pharetra. Donec pretium vulputate sapien nec. Dolor morbi non arcu risus quis varius quam quisque. Blandit turpis cursus in hac habitasse. Est ultricies integer quis auctor elit sed vulputate mi sit. Nunc consequat interdum varius sit amet mattis vulputate enim. Semper feugiat nibh sed pulvinar. Eget felis eget nunc lobortis mattis aliquam. Ultrices vitae auctor eu augue. Tellus molestie nunc non blandit massa enim nec dui. Pharetra massa massa ultricies mi quis hendrerit dolor. Nisl suscipit adipiscing bibendum est ultricies integer.</p><p><a class="mention" href="/profile/u1" data-mention-id="u1" target="_blank">@peter-lustig</a> </p><p></p>',
|
||||
contentExcerpt:
|
||||
'<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium aenean pharetra magna ac …</p>',
|
||||
...post,
|
||||
author: user,
|
||||
},
|
||||
|
||||
@ -72,8 +72,8 @@
|
||||
:class="{ 'notification-status': notification.read }"
|
||||
>
|
||||
{{
|
||||
notification.from.contentExcerpt ||
|
||||
notification.from.descriptionExcerpt | removeHtml
|
||||
$filters.removeHtml(notification.from.content) ||
|
||||
$filters.removeHtml(notification.from.descriptionExcerpt)
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@ -66,9 +66,7 @@
|
||||
/>
|
||||
</div>
|
||||
</client-only>
|
||||
<!-- TODO: replace editor content with tiptap render view -->
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div class="content hyphenate-text" v-html="excerpt" />
|
||||
<div class="content hyphenate-text">{{ excerpt }}</div>
|
||||
<footer
|
||||
class="footer"
|
||||
v-observe-visibility="(isVisible, entry) => visibilityChanged(isVisible, entry, post.id)"
|
||||
@ -232,7 +230,7 @@ export default {
|
||||
user: 'auth/user',
|
||||
}),
|
||||
excerpt() {
|
||||
return this.$filters.removeLinks(this.post.contentExcerpt)
|
||||
return this.$filters.removeHtml(this.post.content)
|
||||
},
|
||||
isAuthor() {
|
||||
const { author } = this.post
|
||||
@ -399,6 +397,10 @@ export default {
|
||||
.content {
|
||||
flex-grow: 1;
|
||||
margin-bottom: $space-small;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 6;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.footer {
|
||||
|
||||
@ -90,7 +90,7 @@ export default {
|
||||
name:
|
||||
report.resource.name ||
|
||||
this.$filters.truncate(report.resource.title, 30) ||
|
||||
this.$filters.truncate(this.$filters.removeHtml(report.resource.contentExcerpt), 30),
|
||||
this.$filters.truncate(this.$filters.removeHtml(report.resource.content), 30),
|
||||
},
|
||||
buttons: {
|
||||
confirm: {
|
||||
|
||||
@ -153,9 +153,7 @@ export default {
|
||||
}
|
||||
},
|
||||
linkText() {
|
||||
return (
|
||||
this.report.resource.title || this.$filters.removeHtml(this.report.resource.contentExcerpt)
|
||||
)
|
||||
return this.report.resource.title || this.$filters.removeHtml(this.report.resource.content)
|
||||
},
|
||||
statusIconName() {
|
||||
return this.isDisabled ? this.icons.eyeSlash : this.icons.eye
|
||||
|
||||
@ -7,7 +7,7 @@ export const notifications = [
|
||||
id: 'post-1',
|
||||
title: 'some post title',
|
||||
slug: 'some-post-title',
|
||||
contentExcerpt: 'this is a post content',
|
||||
content: 'this is a post content',
|
||||
author: {
|
||||
id: 'john-1',
|
||||
slug: 'john-doe',
|
||||
@ -21,12 +21,12 @@ export const notifications = [
|
||||
from: {
|
||||
__typename: 'Comment',
|
||||
id: 'comment-2',
|
||||
contentExcerpt: 'this is yet another post content',
|
||||
content: 'this is yet another post content',
|
||||
post: {
|
||||
id: 'post-1',
|
||||
title: 'some post on a comment',
|
||||
slug: 'some-post-on-a-comment',
|
||||
contentExcerpt: 'this is a post content',
|
||||
content: 'this is a post content',
|
||||
author: {
|
||||
id: 'john-1',
|
||||
slug: 'john-doe',
|
||||
|
||||
@ -9,7 +9,7 @@ export default () => {
|
||||
mutation ($postId: ID!, $content: String!) {
|
||||
CreateComment(postId: $postId, content: $content) {
|
||||
id
|
||||
contentExcerpt
|
||||
|
||||
content
|
||||
createdAt
|
||||
updatedAt
|
||||
@ -45,7 +45,7 @@ export default () => {
|
||||
mutation ($content: String!, $id: ID!) {
|
||||
UpdateComment(content: $content, id: $id) {
|
||||
id
|
||||
contentExcerpt
|
||||
|
||||
content
|
||||
createdAt
|
||||
updatedAt
|
||||
@ -70,7 +70,7 @@ export default () => {
|
||||
mutation ($id: ID!) {
|
||||
DeleteComment(id: $id) {
|
||||
id
|
||||
contentExcerpt
|
||||
|
||||
content
|
||||
createdAt
|
||||
disabled
|
||||
|
||||
@ -8,7 +8,7 @@ export default () => {
|
||||
query Comment($postId: ID) {
|
||||
Comment(postId: $postId) {
|
||||
id
|
||||
contentExcerpt
|
||||
content
|
||||
createdAt
|
||||
author {
|
||||
id
|
||||
|
||||
@ -42,7 +42,7 @@ export const reportsListQuery = () => {
|
||||
}
|
||||
... on Comment {
|
||||
id
|
||||
contentExcerpt
|
||||
content
|
||||
disabled
|
||||
deleted
|
||||
author {
|
||||
|
||||
@ -32,7 +32,7 @@ export default () => {
|
||||
slug
|
||||
title
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
image {
|
||||
...imageUrls
|
||||
@ -83,7 +83,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
image {
|
||||
...imageUrls
|
||||
@ -146,7 +146,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
pinnedBy {
|
||||
id
|
||||
@ -163,7 +163,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
pinnedBy {
|
||||
id
|
||||
@ -180,7 +180,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
pinnedBy {
|
||||
id
|
||||
@ -197,7 +197,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
pinnedBy {
|
||||
id
|
||||
@ -214,7 +214,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
pinnedBy {
|
||||
id
|
||||
@ -231,7 +231,7 @@ export default () => {
|
||||
title
|
||||
slug
|
||||
content
|
||||
contentExcerpt
|
||||
|
||||
language
|
||||
pinnedBy {
|
||||
id
|
||||
|
||||
@ -8,7 +8,6 @@ export const comment = gql`
|
||||
disabled
|
||||
deleted
|
||||
content
|
||||
contentExcerpt
|
||||
isPostObservedByMe
|
||||
postObservingUsersCount
|
||||
shoutedByCurrentUser
|
||||
|
||||
@ -8,7 +8,6 @@ export const post = gql`
|
||||
id
|
||||
title
|
||||
content
|
||||
contentExcerpt
|
||||
createdAt
|
||||
updatedAt
|
||||
sortDate
|
||||
|
||||
@ -434,7 +434,7 @@ export default {
|
||||
id: post.id,
|
||||
slug: post.slug,
|
||||
name: post.title,
|
||||
description: post.contentExcerpt,
|
||||
description: this.$filters.removeHtml(post.content),
|
||||
},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
|
||||
@ -87,11 +87,26 @@ export default ({ app = {} }) => {
|
||||
if (!content) return ''
|
||||
let contentExcerpt = content
|
||||
if (replaceLinebreaks) {
|
||||
// replace linebreaks with spaces first
|
||||
contentExcerpt = contentExcerpt.replace(/<br>/gim, ' ').trim()
|
||||
// replace linebreaks and block-level closing tags with spaces
|
||||
contentExcerpt = contentExcerpt
|
||||
.replace(/<\/(p|h[1-6]|li|div|blockquote)>/gim, ' ')
|
||||
.replace(/<br\s*\/?>/gim, ' ')
|
||||
.trim()
|
||||
}
|
||||
// remove the rest of the HTML
|
||||
contentExcerpt = contentExcerpt.replace(/<(?:.|\n)*?>/gm, '').trim()
|
||||
// normalize multiple spaces into one
|
||||
contentExcerpt = contentExcerpt.replace(/ {2,}/g, ' ')
|
||||
// decode common HTML entities
|
||||
const entities = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
''': "'",
|
||||
' ': ' ',
|
||||
}
|
||||
contentExcerpt = contentExcerpt.replace(/&(?:amp|lt|gt|quot|#39|nbsp);/g, (m) => entities[m])
|
||||
|
||||
return contentExcerpt
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user