diff --git a/backend/src/models/Post.js b/backend/src/models/Post.js
index 59fd31f35..18dc0e464 100644
--- a/backend/src/models/Post.js
+++ b/backend/src/models/Post.js
@@ -39,4 +39,5 @@ module.exports = {
default: () => new Date().toISOString(),
},
language: { type: 'string', allow: [null] },
+ imageAspectRatio: { type: 'float', default: 1.0 },
}
diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js
index 2bd229b84..b37a4abd5 100644
--- a/backend/src/schema/resolvers/posts.js
+++ b/backend/src/schema/resolvers/posts.js
@@ -309,7 +309,15 @@ export default {
},
Post: {
...Resolver('Post', {
- undefinedToNull: ['activityId', 'objectId', 'image', 'language', 'pinnedAt', 'pinned'],
+ undefinedToNull: [
+ 'activityId',
+ 'objectId',
+ 'image',
+ 'language',
+ 'pinnedAt',
+ 'pinned',
+ 'imageAspectRatio',
+ ],
hasMany: {
tags: '-[:TAGGED]->(related:Tag)',
categories: '-[:CATEGORIZED]->(related:Category)',
diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql
index 4837aab1e..0f1817971 100644
--- a/backend/src/schema/types/type/Post.gql
+++ b/backend/src/schema/types/type/Post.gql
@@ -119,6 +119,7 @@ type Post {
contentExcerpt: String
image: String
imageUpload: Upload
+ imageAspectRatio: Float
visibility: Visibility
deleted: Boolean
disabled: Boolean
@@ -182,6 +183,7 @@ type Mutation {
language: String
categoryIds: [ID]
contentExcerpt: String
+ imageAspectRatio: Float
): Post
UpdatePost(
id: ID!
@@ -194,6 +196,7 @@ type Mutation {
visibility: Visibility
language: String
categoryIds: [ID]
+ imageAspectRatio: Float
): Post
DeletePost(id: ID!): Post
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
@@ -218,6 +221,7 @@ type Query {
offset: Int
orderBy: [_PostOrdering]
filter: _PostFilter
+ imageAspectRatio: Float
): [Post]
PostsEmotionsCountByEmotion(postId: ID!, data: _EMOTEDInput!): Int!
PostsEmotionsByCurrentUser(postId: ID!): [String]
diff --git a/backend/src/seed/factories/posts.js b/backend/src/seed/factories/posts.js
index 3058204a1..2443619ae 100644
--- a/backend/src/seed/factories/posts.js
+++ b/backend/src/seed/factories/posts.js
@@ -19,6 +19,7 @@ export default function create() {
visibility: 'public',
deleted: false,
categoryIds: [],
+ imageAspectRatio: 1.333,
}
args = {
...defaults,
diff --git a/backend/src/seed/seed-db.js b/backend/src/seed/seed-db.js
index d059400a4..eaa2f7984 100644
--- a/backend/src/seed/seed-db.js
+++ b/backend/src/seed/seed-db.js
@@ -350,15 +350,17 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
author: peterLustig,
id: 'p0',
language: sample(languages),
- image: faker.image.unsplash.food(),
+ image: faker.image.unsplash.food(300, 169),
categoryIds: ['cat16'],
+ imageAspectRatio: 300 / 169,
}),
factory.create('Post', {
author: bobDerBaumeister,
id: 'p1',
language: sample(languages),
- image: faker.image.unsplash.technology(),
+ image: faker.image.unsplash.technology(300, 1500),
categoryIds: ['cat1'],
+ imageAspectRatio: 300 / 1500,
}),
factory.create('Post', {
author: huey,
@@ -382,8 +384,9 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
authorId: 'u1',
id: 'p6',
language: sample(languages),
- image: faker.image.unsplash.buildings(),
+ image: faker.image.unsplash.buildings(300, 857),
categoryIds: ['cat6'],
+ imageAspectRatio: 300 / 857,
}),
factory.create('Post', {
author: huey,
@@ -400,8 +403,9 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
author: louie,
id: 'p11',
language: sample(languages),
- image: faker.image.unsplash.people(),
+ image: faker.image.unsplash.people(300, 901),
categoryIds: ['cat11'],
+ imageAspectRatio: 300 / 901,
}),
factory.create('Post', {
author: bobDerBaumeister,
@@ -413,8 +417,9 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
author: jennyRostock,
id: 'p14',
language: sample(languages),
- image: faker.image.unsplash.objects(),
+ image: faker.image.unsplash.objects(300, 200),
categoryIds: ['cat14'],
+ imageAspectRatio: 300 / 450,
}),
factory.create('Post', {
author: huey,
@@ -434,8 +439,20 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
const hashtagAndMention1 =
'The new physics of #QuantenFlussTheorie can explain #QuantumGravity! @peter-lustig got that already. ;-)'
const createPostMutation = gql`
- mutation($id: ID, $title: String!, $content: String!, $categoryIds: [ID]) {
- CreatePost(id: $id, title: $title, content: $content, categoryIds: $categoryIds) {
+ mutation(
+ $id: ID
+ $title: String!
+ $content: String!
+ $categoryIds: [ID]
+ $imageAspectRatio: Float
+ ) {
+ CreatePost(
+ id: $id
+ title: $title
+ content: $content
+ categoryIds: $categoryIds
+ imageAspectRatio: $imageAspectRatio
+ ) {
id
}
}
@@ -449,6 +466,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
title: `Nature Philosophy Yoga`,
content: hashtag1,
categoryIds: ['cat2'],
+ imageAspectRatio: 300 / 200,
},
}),
mutate({
@@ -458,6 +476,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
title: 'This is post #7',
content: `${mention1} ${faker.lorem.paragraph()}`,
categoryIds: ['cat7'],
+ imageAspectRatio: 300 / 180,
},
}),
mutate({
@@ -468,6 +487,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
title: `Quantum Flow Theory explains Quantum Gravity`,
content: hashtagAndMention1,
categoryIds: ['cat8'],
+ imageAspectRatio: 300 / 900,
},
}),
mutate({
@@ -477,6 +497,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
title: 'This is post #12',
content: `${mention2} ${faker.lorem.paragraph()}`,
categoryIds: ['cat12'],
+ imageAspectRatio: 300 / 200,
},
}),
])
diff --git a/neo4j/db_manipulation/add_image_aspect_ratio.sh b/neo4j/db_manipulation/add_image_aspect_ratio.sh
new file mode 100755
index 000000000..7fe2c5871
--- /dev/null
+++ b/neo4j/db_manipulation/add_image_aspect_ratio.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+if [ -z "$NEO4J_USERNAME" ] || [ -z "$NEO4J_PASSWORD" ]; then
+ echo "Please set NEO4J_USERNAME and NEO4J_PASSWORD environment variables."
+ echo "Database manipulation is not possible without connecting to the database."
+ echo "E.g. you could \`cp .env.template .env\` unless you run the script in a docker container"
+fi
+
+until echo 'RETURN "Connection successful" as info;' | cypher-shell
+do
+ echo "Connecting to neo4j failed, trying again..."
+ sleep 1
+done
+
+shopt -s nullglob
+for image in uploads/*; do
+ [ -e "$image" ] || continue
+ IMAGE_WIDTH=$( identify -format '%w' "$image" )
+ IMAGE_HEIGHT=$( identify -format '%h' "$image" )
+ IMAGE_ASPECT_RATIO=$(echo | awk "{ print ${IMAGE_WIDTH}/${IMAGE_HEIGHT}}")
+
+
+ echo "$image"
+ echo "$IMAGE_ASPECT_RATIO"
+ echo "
+ match (post:Post {image: '/"${image}"'})
+ set post.imageAspectRatio = "${IMAGE_ASPECT_RATIO}"
+ return post;
+ " | cypher-shell
+done
diff --git a/webapp/components/ContributionForm/ContributionForm.spec.js b/webapp/components/ContributionForm/ContributionForm.spec.js
index 3ec538bde..8c50f30b6 100644
--- a/webapp/components/ContributionForm/ContributionForm.spec.js
+++ b/webapp/components/ContributionForm/ContributionForm.spec.js
@@ -198,6 +198,7 @@ describe('ContributionForm.vue', () => {
id: null,
categoryIds: ['cat12'],
imageUpload: null,
+ imageAspectRatio: null,
image: null,
},
}
@@ -352,6 +353,7 @@ describe('ContributionForm.vue', () => {
categoryIds: ['cat12'],
image,
imageUpload: null,
+ imageAspectRatio: null,
},
}
})
diff --git a/webapp/components/ContributionForm/ContributionForm.vue b/webapp/components/ContributionForm/ContributionForm.vue
index 734e3be81..ec9fe9616 100644
--- a/webapp/components/ContributionForm/ContributionForm.vue
+++ b/webapp/components/ContributionForm/ContributionForm.vue
@@ -7,7 +7,11 @@
@submit="submit"
>
-
+
{
@@ -227,6 +234,9 @@ export default {
addTeaserImage(file) {
this.form.teaserImage = file
},
+ addImageAspectRatio(aspectRatio) {
+ this.form.imageAspectRatio = aspectRatio
+ },
categoryIds(categories) {
return categories.map(c => c.id)
},
diff --git a/webapp/components/MasonryGrid/MasonryGrid.spec.js b/webapp/components/MasonryGrid/MasonryGrid.spec.js
index 8eed5e150..b42b9b221 100644
--- a/webapp/components/MasonryGrid/MasonryGrid.spec.js
+++ b/webapp/components/MasonryGrid/MasonryGrid.spec.js
@@ -6,23 +6,36 @@ const localVue = global.localVue
describe('MasonryGrid', () => {
let wrapper
- let masonryGrid
+ let masonryGridItem
beforeEach(() => {
wrapper = mount(MasonryGrid, { localVue })
- masonryGrid = wrapper.vm.$children[0]
+ masonryGridItem = wrapper.vm.$children[0]
})
- it('adds the "reset-grid-height" class when one or more children are updating', () => {
- masonryGrid.$emit('calculating-item-height')
+ it('adds the "reset-grid-height" class when itemsCalculating is more than 0', () => {
+ wrapper.setData({ itemsCalculating: 1 })
expect(wrapper.classes()).toContain('reset-grid-height')
})
- it('removes the "reset-grid-height" class when all children have completed updating', () => {
- wrapper.setData({ itemsCalculating: 1 })
- masonryGrid.$emit('finished-calculating-item-height')
+ it('removes the "reset-grid-height" class when itemsCalculating is 0', () => {
+ wrapper.setData({ itemsCalculating: 0 })
expect(wrapper.classes()).not.toContain('reset-grid-height')
})
+
+ it('adds 1 to itemsCalculating when a child emits "calculating-item-height"', () => {
+ wrapper.setData({ itemsCalculating: 0 })
+ masonryGridItem.$emit('calculating-item-height')
+
+ expect(wrapper.vm.itemsCalculating).toBe(1)
+ })
+
+ it('subtracts 1 from itemsCalculating when a child emits "finished-calculating-item-height"', () => {
+ wrapper.setData({ itemsCalculating: 2 })
+ masonryGridItem.$emit('finished-calculating-item-height')
+
+ expect(wrapper.vm.itemsCalculating).toBe(1)
+ })
})
diff --git a/webapp/components/MasonryGrid/MasonryGrid.vue b/webapp/components/MasonryGrid/MasonryGrid.vue
index c27f134e8..5ef8f9006 100644
--- a/webapp/components/MasonryGrid/MasonryGrid.vue
+++ b/webapp/components/MasonryGrid/MasonryGrid.vue
@@ -1,6 +1,5 @@
-