diff --git a/webapp/app/router.scrollBehavior.js b/webapp/app/router.scrollBehavior.js
new file mode 100644
index 000000000..d34c4c38a
--- /dev/null
+++ b/webapp/app/router.scrollBehavior.js
@@ -0,0 +1,10 @@
+export default function(to, from, savedPosition) {
+ if (savedPosition) return savedPosition
+
+ // Edge case: If you click on a notification from a comment and then on the
+ // post page you click on 'comments', we avoid a "jumping" scroll behavior,
+ // ie. jump to the top and scroll back from there
+ if (to.path === from.path && to.hash !== from.hash) return false
+
+ return { x: 0, y: 0 }
+}
diff --git a/webapp/components/Comment/Comment.spec.js b/webapp/components/Comment/Comment.spec.js
index 381d49bc2..59e3f6c5a 100644
--- a/webapp/components/Comment/Comment.spec.js
+++ b/webapp/components/Comment/Comment.spec.js
@@ -32,6 +32,7 @@ describe('Comment.vue', () => {
truncate: a => a,
removeHtml: a => a,
},
+ $scrollTo: jest.fn(),
$apollo: {
mutate: jest.fn().mockResolvedValue({
data: {
@@ -51,6 +52,8 @@ describe('Comment.vue', () => {
})
describe('shallowMount', () => {
+ beforeEach(jest.useFakeTimers)
+
Wrapper = () => {
const store = new Vuex.Store({
getters,
@@ -117,7 +120,35 @@ describe('Comment.vue', () => {
})
})
- beforeEach(jest.useFakeTimers)
+ describe('scrollToAnchor mixin', () => {
+ describe('$route.hash !== comment.id', () => {
+ beforeEach(() => {
+ mocks.$route = {
+ hash: '',
+ }
+ })
+
+ it('skips $scrollTo', () => {
+ wrapper = Wrapper()
+ jest.runAllTimers()
+ expect(mocks.$scrollTo).not.toHaveBeenCalled()
+ })
+ })
+
+ describe('$route.hash === comment.id', () => {
+ beforeEach(() => {
+ mocks.$route = {
+ hash: '#commentId-2',
+ }
+ })
+
+ it('calls $scrollTo', () => {
+ wrapper = Wrapper()
+ jest.runAllTimers()
+ expect(mocks.$scrollTo).toHaveBeenCalledWith('#commentId-2')
+ })
+ })
+ })
describe('test callbacks', () => {
beforeEach(() => {
diff --git a/webapp/components/Comment/Comment.vue b/webapp/components/Comment/Comment.vue
index 49f29bfe9..31bbc811f 100644
--- a/webapp/components/Comment/Comment.vue
+++ b/webapp/components/Comment/Comment.vue
@@ -10,7 +10,7 @@
-
+
@@ -80,8 +80,10 @@ import ContentMenu from '~/components/ContentMenu'
import ContentViewer from '~/components/Editor/ContentViewer'
import HcCommentForm from '~/components/CommentForm/CommentForm'
import CommentMutations from '~/graphql/CommentMutations'
+import scrollToAnchor from '~/mixins/scrollToAnchor.js'
export default {
+ mixins: [scrollToAnchor],
data: function() {
return {
isCollapsed: true,
@@ -109,6 +111,9 @@ export default {
user: 'auth/user',
isModerator: 'auth/isModerator',
}),
+ anchor() {
+ return `commentId-${this.comment.id}`
+ },
displaysComment() {
return !this.unavailable || this.isModerator
},
@@ -142,6 +147,9 @@ export default {
},
},
methods: {
+ checkAnchor(anchor) {
+ return `#${this.anchor}` === anchor
+ },
isAuthor(id) {
return this.user.id === id
},
diff --git a/webapp/components/CommentList/CommentList.spec.js b/webapp/components/CommentList/CommentList.spec.js
index 4d382b36d..3287b7cd4 100644
--- a/webapp/components/CommentList/CommentList.spec.js
+++ b/webapp/components/CommentList/CommentList.spec.js
@@ -42,6 +42,7 @@ describe('CommentList.vue', () => {
truncate: a => a,
removeHtml: a => a,
},
+ $scrollTo: jest.fn(),
$apollo: {
queries: {
Post: {
@@ -65,12 +66,46 @@ describe('CommentList.vue', () => {
})
}
- beforeEach(() => {
+ it('displays a comments counter', () => {
wrapper = Wrapper()
+ expect(wrapper.find('span.ds-tag').text()).toEqual('1')
})
it('displays a comments counter', () => {
+ wrapper = Wrapper()
expect(wrapper.find('span.ds-tag').text()).toEqual('1')
})
+
+ describe('scrollToAnchor mixin', () => {
+ beforeEach(jest.useFakeTimers)
+
+ describe('$route.hash !== `#comments`', () => {
+ beforeEach(() => {
+ mocks.$route = {
+ hash: '',
+ }
+ })
+
+ it('skips $scrollTo', () => {
+ wrapper = Wrapper()
+ jest.runAllTimers()
+ expect(mocks.$scrollTo).not.toHaveBeenCalled()
+ })
+ })
+
+ describe('$route.hash === `#comments`', () => {
+ beforeEach(() => {
+ mocks.$route = {
+ hash: '#comments',
+ }
+ })
+
+ it('calls $scrollTo', () => {
+ wrapper = Wrapper()
+ jest.runAllTimers()
+ expect(mocks.$scrollTo).toHaveBeenCalledWith('#comments')
+ })
+ })
+ })
})
})
diff --git a/webapp/components/CommentList/CommentList.vue b/webapp/components/CommentList/CommentList.vue
index 6061847d7..f1cdf910b 100644
--- a/webapp/components/CommentList/CommentList.vue
+++ b/webapp/components/CommentList/CommentList.vue
@@ -30,8 +30,10 @@
diff --git a/webapp/pages/post/_id/_slug/index.vue b/webapp/pages/post/_id/_slug/index.vue
index d03cd5c70..0fda144d0 100644
--- a/webapp/pages/post/_id/_slug/index.vue
+++ b/webapp/pages/post/_id/_slug/index.vue
@@ -197,7 +197,7 @@ export default {
.ds-card-image {
img {
- max-height: 300px;
+ height: 300px;
object-fit: cover;
object-position: center;
}
diff --git a/webapp/yarn.lock b/webapp/yarn.lock
index 634a42a19..cf0c4095d 100644
--- a/webapp/yarn.lock
+++ b/webapp/yarn.lock
@@ -4235,6 +4235,11 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
+bezier-easing@2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/bezier-easing/-/bezier-easing-2.1.0.tgz#c04dfe8b926d6ecaca1813d69ff179b7c2025d86"
+ integrity sha1-wE3+i5JtbsrKGBPWn/F5t8ICXYY=
+
bfj@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.1.tgz#05a3b7784fbd72cfa3c22e56002ef99336516c48"
@@ -15307,6 +15312,13 @@ vue-router@~3.0.7:
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.0.7.tgz#b36ca107b4acb8ff5bc4ff824584059c23fcb87b"
integrity sha512-utJ+QR3YlIC/6x6xq17UMXeAfxEvXA0VKD3PiSio7hBOZNusA1jXcbxZxVEfJunLp48oonjTepY8ORoIlRx/EQ==
+vue-scrollto@^2.17.1:
+ version "2.17.1"
+ resolved "https://registry.yarnpkg.com/vue-scrollto/-/vue-scrollto-2.17.1.tgz#cd62ee0b98cf7e2ba9fd94f029addcd093978a48"
+ integrity sha512-uxOJXg6cZL88B+hTXRHDJMR+gHGiaS70ZTNk55fE5Z2TdwyIx9K/IHoNeTrtBrM6u3FASAIymKjZaQLmDf8Ykg==
+ dependencies:
+ bezier-easing "2.1.0"
+
vue-server-renderer@^2.6.10:
version "2.6.10"
resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz#cb2558842ead360ae2ec1f3719b75564a805b375"