From 750c308909b76be5d4572c86b4affb6aed41f47b Mon Sep 17 00:00:00 2001 From: taehoon Date: Sun, 10 Feb 2019 13:23:01 -0500 Subject: [PATCH 1/4] Support lightbox gallery navigation via arrow buttons and keyboard --- src/components/media_modal/media_modal.js | 51 ++++++++++++--- src/components/media_modal/media_modal.vue | 74 +++++++++++++++++++++- 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/components/media_modal/media_modal.js b/src/components/media_modal/media_modal.js index 14ae19d404..992d7129d7 100644 --- a/src/components/media_modal/media_modal.js +++ b/src/components/media_modal/media_modal.js @@ -11,27 +11,62 @@ const MediaModal = { showing () { return this.$store.state.mediaViewer.activated }, + media () { + return this.$store.state.mediaViewer.media + }, currentIndex () { return this.$store.state.mediaViewer.currentIndex }, currentMedia () { - return this.$store.state.mediaViewer.media[this.currentIndex] + return this.media[this.currentIndex] + }, + canNavigate () { + return this.media.length > 1 }, type () { return this.currentMedia ? fileTypeService.fileType(this.currentMedia.mimetype) : null } }, - created () { - document.addEventListener('keyup', e => { - if (e.keyCode === 27 && this.showing) { // escape - this.hide() - } - }) - }, methods: { hide () { this.$store.dispatch('closeMediaViewer') + }, + goPrev () { + if (this.canNavigate) { + const prevIndex = this.currentIndex === 0 ? this.media.length - 1 : (this.currentIndex - 1) + this.$store.dispatch('setCurrent', this.media[prevIndex]) + } + }, + goNext () { + if (this.canNavigate) { + const nextIndex = this.currentIndex === this.media.length - 1 ? 0 : (this.currentIndex + 1) + this.$store.dispatch('setCurrent', this.media[nextIndex]) + } + }, + handleKeyupEvent (e) { + if (this.showing && e.keyCode === 27) { // escape + this.hide() + } + }, + handleKeydownEvent (e) { + if (!this.showing) { + return + } + + if (e.keyCode === 39) { // arrow right + this.goNext() + } else if (e.keyCode === 37) { // arrow left + this.goPrev() + } } + }, + mounted () { + document.addEventListener('keyup', this.handleKeyupEvent) + document.addEventListener('keydown', this.handleKeydownEvent) + }, + destroyed () { + document.removeEventListener('keyup', this.handleKeyupEvent) + document.removeEventListener('keydown', this.handleKeydownEvent) } } diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue index 796d4e403a..fbaa97f8cb 100644 --- a/src/components/media_modal/media_modal.vue +++ b/src/components/media_modal/media_modal.vue @@ -8,6 +8,8 @@ :controls="true" @click.stop.native=""> + + @@ -19,15 +21,81 @@ .modal-view { z-index: 1000; position: fixed; - width: 100vw; - height: 100vh; top: 0; left: 0; + right: 0; + bottom: 0; display: flex; justify-content: center; align-items: center; background-color: rgba(0, 0, 0, 0.5); - cursor: pointer; + + &-button-arrow { + position: absolute; + display: block; + top: 50%; + margin-top: -50px; + width: 70px; + height: 100px; + border: 0; + padding: 0; + opacity: 0; + box-shadow: none; + background: none; + appearance: none; + overflow: visible; + cursor: pointer; + transition: opacity 333ms cubic-bezier(.4,0,.22,1); + + &:before { + position: absolute; + top: 35px; + height: 30px; + width: 32px; + font-family: "fontello"; + font-size: 14px; + line-height: 30px; + color: #FFF; + text-align: center; + background-color: rgba(0,0,0,.3); + } + + &:hover, + &:focus { + outline: none; + box-shadow: none; + } + + &#{&}#{&} { + &:hover { + opacity: 1; + } + } + + &--prev { + left: 0; + + &:before { + left: 6px; + content: '\e80e'; + } + } + + &--next { + right: 0; + + &:before { + right: 6px; + content: '\e80d'; + } + } + } + + &:hover { + .modal-view-button-arrow { + opacity: .75; + } + } } .modal-image { From 971e75aa64ddd9f2f4a658eb51e09afd23600d1b Mon Sep 17 00:00:00 2001 From: taehoon Date: Sun, 10 Feb 2019 13:26:08 -0500 Subject: [PATCH 2/4] Add translation strings --- src/components/media_modal/media_modal.vue | 6 +++--- src/i18n/en.json | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue index fbaa97f8cb..306c1a890c 100644 --- a/src/components/media_modal/media_modal.vue +++ b/src/components/media_modal/media_modal.vue @@ -8,8 +8,8 @@ :controls="true" @click.stop.native=""> - - + + @@ -65,7 +65,7 @@ outline: none; box-shadow: none; } - + &#{&}#{&} { &:hover { opacity: 1; diff --git a/src/i18n/en.json b/src/i18n/en.json index c664fbfaeb..14e2a699a2 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -31,6 +31,10 @@ "username": "Username", "hint": "Log in to join the discussion" }, + "media_modal": { + "previous": "Previous", + "next": "Next" + }, "nav": { "about": "About", "back": "Back", From a20974faac46bfe61ef638e881082fc52219dd54 Mon Sep 17 00:00:00 2001 From: taehoon Date: Mon, 11 Feb 2019 06:56:46 -0500 Subject: [PATCH 3/4] Use correct syntax for pseudoelement --- src/components/media_modal/media_modal.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue index 306c1a890c..8cd183ec53 100644 --- a/src/components/media_modal/media_modal.vue +++ b/src/components/media_modal/media_modal.vue @@ -47,7 +47,7 @@ cursor: pointer; transition: opacity 333ms cubic-bezier(.4,0,.22,1); - &:before { + &::before { position: absolute; top: 35px; height: 30px; @@ -75,7 +75,7 @@ &--prev { left: 0; - &:before { + &::before { left: 6px; content: '\e80e'; } @@ -84,7 +84,7 @@ &--next { right: 0; - &:before { + &::before { right: 6px; content: '\e80d'; } From 4e0f934301dbbabc461a55e373d844e3609b91fd Mon Sep 17 00:00:00 2001 From: shpuld Date: Tue, 19 Feb 2019 18:33:40 +0200 Subject: [PATCH 4/4] Clean up CSS a bit --- src/components/media_modal/media_modal.vue | 131 +++++++++++---------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue index 8cd183ec53..427bf12b06 100644 --- a/src/components/media_modal/media_modal.vue +++ b/src/components/media_modal/media_modal.vue @@ -8,8 +8,22 @@ :controls="true" @click.stop.native=""> - - + + @@ -30,71 +44,19 @@ align-items: center; background-color: rgba(0, 0, 0, 0.5); - &-button-arrow { - position: absolute; - display: block; - top: 50%; - margin-top: -50px; - width: 70px; - height: 100px; - border: 0; - padding: 0; - opacity: 0; - box-shadow: none; - background: none; - appearance: none; - overflow: visible; - cursor: pointer; - transition: opacity 333ms cubic-bezier(.4,0,.22,1); + &:hover { + .modal-view-button-arrow { + opacity: 0.75; - &::before { - position: absolute; - top: 35px; - height: 30px; - width: 32px; - font-family: "fontello"; - font-size: 14px; - line-height: 30px; - color: #FFF; - text-align: center; - background-color: rgba(0,0,0,.3); - } - - &:hover, - &:focus { - outline: none; - box-shadow: none; - } - - &#{&}#{&} { + &:focus, + &:hover { + outline: none; + box-shadow: none; + } &:hover { opacity: 1; } } - - &--prev { - left: 0; - - &::before { - left: 6px; - content: '\e80e'; - } - } - - &--next { - right: 0; - - &::before { - right: 6px; - content: '\e80d'; - } - } - } - - &:hover { - .modal-view-button-arrow { - opacity: .75; - } } } @@ -103,4 +65,49 @@ max-height: 90%; box-shadow: 0px 5px 15px 0 rgba(0, 0, 0, 0.5); } + +.modal-view-button-arrow { + position: absolute; + display: block; + top: 50%; + margin-top: -50px; + width: 70px; + height: 100px; + border: 0; + padding: 0; + opacity: 0; + box-shadow: none; + background: none; + appearance: none; + overflow: visible; + cursor: pointer; + transition: opacity 333ms cubic-bezier(.4,0,.22,1); + + .arrow-icon { + position: absolute; + top: 35px; + height: 30px; + width: 32px; + font-size: 14px; + line-height: 30px; + color: #FFF; + text-align: center; + background-color: rgba(0,0,0,.3); + } + + &--prev { + left: 0; + .arrow-icon { + left: 6px; + } + } + + &--next { + right: 0; + .arrow-icon { + right: 6px; + } + } +} +