Merge pull request #2351 from Human-Connection/1746-Blur_explicit_Image_Content

Blur Images
This commit is contained in:
Wolfgang Huß 2019-12-19 11:46:38 +01:00 committed by GitHub
commit 377f2eecd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 164 additions and 73 deletions

View File

@ -8,5 +8,4 @@
}
],
"editor.formatOnSave": false,
"eslint.autoFixOnSave": true
}

View File

@ -39,5 +39,6 @@ module.exports = {
default: () => new Date().toISOString(),
},
language: { type: 'string', allow: [null] },
imageBlurred: { type: 'boolean', default: false },
imageAspectRatio: { type: 'float', default: 1.0 },
}

View File

@ -341,6 +341,7 @@ export default {
'language',
'pinnedAt',
'pinned',
'imageBlurred',
'imageAspectRatio',
],
hasMany: {

View File

@ -82,6 +82,7 @@ input _PostFilter {
emotions_none: _PostEMOTEDFilter
emotions_single: _PostEMOTEDFilter
emotions_every: _PostEMOTEDFilter
imageBlurred: Boolean
}
enum _PostOrdering {
@ -127,6 +128,7 @@ type Post {
createdAt: String
updatedAt: String
language: String
imageBlurred: Boolean
pinnedAt: String @cypher(
statement: "MATCH (this)<-[pinned:PINNED]-(:User) WHERE NOT this.deleted = true AND NOT this.disabled = true RETURN pinned.createdAt"
)
@ -140,7 +142,6 @@ type Post {
LIMIT 10
"""
)
tags: [Tag]! @relation(name: "TAGGED", direction: "OUT")
categories: [Category]! @relation(name: "CATEGORIZED", direction: "OUT")
@ -183,6 +184,7 @@ type Mutation {
language: String
categoryIds: [ID]
contentExcerpt: String
imageBlurred: Boolean
imageAspectRatio: Float
): Post
UpdatePost(
@ -196,6 +198,7 @@ type Mutation {
visibility: Visibility
language: String
categoryIds: [ID]
imageBlurred: Boolean
imageAspectRatio: Float
): Post
DeletePost(id: ID!): Post
@ -217,6 +220,7 @@ type Query {
createdAt: String
updatedAt: String
language: String
imageBlurred: Boolean
first: Int
offset: Int
orderBy: [_PostOrdering]

View File

@ -19,6 +19,7 @@ export default function create() {
visibility: 'public',
deleted: false,
categoryIds: [],
imageBlurred: false,
imageAspectRatio: 1.333,
}
args = {

View File

@ -352,6 +352,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
language: sample(languages),
image: faker.image.unsplash.food(300, 169),
categoryIds: ['cat16'],
imageBlurred: true,
imageAspectRatio: 300 / 169,
}),
factory.create('Post', {
@ -398,6 +399,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
author: dewey,
id: 'p10',
categoryIds: ['cat10'],
imageBlurred: true,
}),
factory.create('Post', {
author: louie,
@ -444,6 +446,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
$title: String!
$content: String!
$categoryIds: [ID]
$imageBlurred: Boolean
$imageAspectRatio: Float
) {
CreatePost(
@ -451,6 +454,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
title: $title
content: $content
categoryIds: $categoryIds
imageBlurred: $imageBlurred
imageAspectRatio: $imageAspectRatio
) {
id

View File

@ -200,6 +200,7 @@ describe('ContributionForm.vue', () => {
imageUpload: null,
imageAspectRatio: null,
image: null,
imageBlurred: false,
},
}
postTitleInput = wrapper.find('.ds-input')

View File

@ -10,6 +10,7 @@
<hc-teaser-image
:contribution="contribution"
@addTeaserImage="addTeaserImage"
:class="{ '--blur-image': form.blurImage }"
@addImageAspectRatio="addImageAspectRatio"
>
<img
@ -18,7 +19,23 @@
:src="contribution.image | proxyApiUrl"
/>
</hc-teaser-image>
<ds-card>
<div class="blur-toggle">
<label for="blur-img">{{ $t('contribution.inappropriatePicture') }}</label>
<input type="checkbox" id="blur-img" v-model="form.blurImage" />
<p>
<a
href="https://support.human-connection.org/kb/faq.php?id=113"
target="_blank"
class="link"
>
{{ $t('contribution.inappropriatePictureText') }}
<ds-icon name="question-circle" />
</a>
</p>
</div>
<ds-space />
<client-only>
<hc-user :user="currentUser" :trunc="35" />
@ -80,6 +97,7 @@
<ds-icon name="warning"></ds-icon>
</ds-chip>
</ds-text>
<ds-space />
<div slot="footer" style="text-align: right">
<ds-button
@ -134,7 +152,9 @@ export default {
image: null,
language: null,
categoryIds: [],
blurImage: false,
}
let id = null
let slug = null
const form = { ...formDefaults }
@ -149,7 +169,9 @@ export default {
? languageOptions.find(o => this.contribution.language === o.value)
: null
form.categoryIds = this.categoryIds(this.contribution.categories)
form.blurImage = this.contribution.imageBlurred
}
return {
form,
formSchema: {
@ -167,6 +189,7 @@ export default {
},
},
language: { required: true },
blurImage: { required: false },
},
languageOptions,
id,
@ -175,6 +198,7 @@ export default {
users: [],
contentMin: 3,
hashtags: [],
elem: null,
}
},
computed: {
@ -195,6 +219,7 @@ export default {
teaserImage,
imageAspectRatio,
categoryIds,
blurImage,
} = this.form
this.loading = true
this.$apollo
@ -208,6 +233,7 @@ export default {
language,
image,
imageUpload: teaserImage,
imageBlurred: blurImage,
imageAspectRatio,
},
})
@ -273,28 +299,35 @@ export default {
}
</script>
<style lang="scss" scoped>
.smallTag {
width: 100%;
position: relative;
left: 90%;
}
.post-title {
margin-top: $space-x-small;
margin-bottom: $space-xx-small;
input {
border: 0;
font-size: $font-size-x-large;
font-weight: bold;
padding-left: 0;
padding-right: 0;
}
}
<style lang="scss">
.contribution-form {
.ds-card-image.--blur-image img {
filter: blur(32px);
}
.blur-toggle {
text-align: right;
> .link {
display: block;
}
}
.ds-chip {
cursor: default;
}
.post-title {
margin-top: $space-x-small;
margin-bottom: $space-xx-small;
input {
border: 0;
font-size: $font-size-x-large;
font-weight: bold;
padding-left: 0;
padding-right: 0;
}
}
}
</style>

View File

@ -2,7 +2,12 @@
<ds-card
:lang="post.language"
:image="post.image | proxyApiUrl"
:class="{ 'post-card': true, 'disabled-content': post.disabled, 'post--pinned': isPinned }"
:class="{
'post-card': true,
'disabled-content': post.disabled,
'--pinned': isPinned,
'--blur-image': post.imageBlurred,
}"
>
<!-- Post Link Target -->
<nuxt-link
@ -151,23 +156,26 @@ export default {
},
}
</script>
<style scoped lang="scss">
.ds-card-image img {
width: 100%;
max-height: 2000px;
object-fit: contain;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: center;
object-position: center;
}
<style lang="scss">
.post-card {
cursor: pointer;
justify-content: space-between;
position: relative;
z-index: 1;
justify-content: space-between;
cursor: pointer;
&.--pinned {
border: 1px solid $color-warning;
}
&.--blur-image > .ds-card-image img {
filter: blur(22px);
}
> .ds-card-image img {
width: 100%;
max-height: 2000px;
object-fit: contain;
}
> .ds-card-content {
flex-grow: 0;
@ -200,8 +208,4 @@ export default {
text-indent: -999999px;
}
}
.post--pinned {
border: 1px solid $color-warning;
}
</style>

View File

@ -140,7 +140,7 @@ export default {
<style lang="scss">
#postdropzone {
width: 100%;
min-height: 500px;
min-height: 400px;
background-color: $background-color-softest;
}

View File

@ -45,6 +45,10 @@ export const postFragment = gql`
slug
image
language
imageBlurred
author {
...user
}
pinnedAt
imageAspectRatio
}

View File

@ -9,6 +9,7 @@ export default () => {
$language: String
$categoryIds: [ID]
$imageUpload: Upload
$imageBlurred: Boolean
$imageAspectRatio: Float
) {
CreatePost(
@ -17,6 +18,7 @@ export default () => {
language: $language
categoryIds: $categoryIds
imageUpload: $imageUpload
imageBlurred: $imageBlurred
imageAspectRatio: $imageAspectRatio
) {
title
@ -24,6 +26,7 @@ export default () => {
content
contentExcerpt
language
imageBlurred
}
}
`,
@ -36,6 +39,7 @@ export default () => {
$imageUpload: Upload
$categoryIds: [ID]
$image: String
$imageBlurred: Boolean
$imageAspectRatio: Float
) {
UpdatePost(
@ -46,6 +50,7 @@ export default () => {
imageUpload: $imageUpload
categoryIds: $categoryIds
image: $image
imageBlurred: $imageBlurred
imageAspectRatio: $imageAspectRatio
) {
id
@ -54,6 +59,7 @@ export default () => {
content
contentExcerpt
language
imageBlurred
pinnedBy {
id
name

View File

@ -452,6 +452,7 @@
"filterALL": "Alle Beiträge anzeigen",
"success": "Gespeichert!",
"languageSelectLabel": "Sprache",
"languageSelectText": "Sprache wählen",
"categories": {
"infoSelectedNoOfMaxCategories": "{chosen} von {max} Kategorien ausgewählt"
},
@ -484,8 +485,9 @@
},
"teaserImage": {
"cropperConfirm": "Bestätigen"
},
"languageSelectText": "Sprache wählen"
},
"inappropriatePicture" : "Dieses Bild kann für einige Menschen unangemessen sein.",
"inappropriatePictureText" : "Wann soll ein Foto versteckt werden"
},
"comment": {
"edit": "Kommentar bearbeiten",

View File

@ -702,7 +702,9 @@
},
"teaserImage": {
"cropperConfirm": "Confirm"
}
},
"inappropriatePicture" : "This image may be inappropriate for some people.",
"inappropriatePictureText" : "When should my picture be blurred"
},
"code-of-conduct": {
"subheader": "for the social network of the Human Connection gGmbH",
@ -802,4 +804,3 @@

View File

@ -4,9 +4,16 @@
:lang="post.language"
v-if="post && ready"
:image="post.image | proxyApiUrl"
:class="{ 'post-card': true, 'disabled-content': post.disabled }"
:class="{
'post-page': true,
'disabled-content': post.disabled,
'--blur-image': blurred,
}"
>
<ds-space margin-bottom="small" />
<aside v-show="post.imageBlurred" class="blur-toggle">
<img v-show="blurred" :src="post.image | proxyApiUrl" class="preview" />
<ds-button :icon="blurred ? 'eye' : 'eye-slash'" primary @click="blurred = !blurred" />
</aside>
<hc-user :user="post.author" :date-time="post.createdAt">
<template v-slot:dateTime>
<ds-text v-if="post.createdAt !== post.updatedAt">({{ $t('post.edited') }})</ds-text>
@ -125,12 +132,14 @@ export default {
ready: false,
title: 'loading',
showNewCommentForm: true,
blurred: false,
}
},
watch: {
Post(post) {
this.post = post[0] || {}
this.title = this.post.title
this.blurred = this.post.imageBlurred
},
},
mounted() {
@ -206,49 +215,70 @@ export default {
},
}
</script>
<style lang="scss">
.page-name-post-id-slug {
.post-page {
&.--blur-image > .ds-card-image img {
filter: blur(22px);
}
.ds-card-content {
position: relative;
padding-top: 24px;
}
.blur-toggle {
position: absolute;
top: -80px;
right: 0;
display: flex;
align-items: center;
height: 80px;
padding: 12px;
.preview {
height: 100%;
margin-right: 12px;
}
}
.content-menu {
float: right;
margin-right: -$space-x-small;
margin-top: -$space-large;
}
.post-card {
margin: auto;
cursor: auto;
.comments {
margin-top: $space-small;
.comments {
.comment {
margin-top: $space-small;
.comment {
margin-top: $space-small;
position: relative;
}
.ProseMirror {
min-height: 0px;
}
position: relative;
}
.ds-card-image {
img {
max-height: 2000px;
object-fit: contain;
object-position: center;
}
.ProseMirror {
min-height: 0px;
}
}
.ds-card-footer {
padding: 0;
.ds-card-image {
img {
max-height: 2000px;
object-fit: contain;
object-position: center;
}
}
.ds-section {
padding: $space-base;
}
.ds-card-footer {
padding: 0;
.ds-section {
padding: $space-base;
}
}
}
@media only screen and (max-width: 960px) {
.shout-button {
float: left;