Skip to content

Commit

Permalink
Implement image viewer pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
acid-chicken committed Jul 16, 2019
1 parent 499a9d0 commit d08c712
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 20 deletions.
131 changes: 126 additions & 5 deletions src/client/app/common/views/components/image-viewer.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<template>
<div class="dkjvrdxtkvqrwmhfickhndpmnncsgacq">
<div class="dkjvrdxtkvqrwmhfickhndpmnncsgacq" v-hotkey.global="keymap">
<div class="bg" @click="close"></div>
<img :src="image.url" :alt="image.name" :title="image.name" @click="close"/>
<img :src="image.url" :alt="image.name" :title="image.name" @click="close" ref="rotator"/>
<div class="paginator left" @click="left"><fa :icon="['fal', 'angle-left']"/></div>
<div class="paginator right" @click="right"><fa :icon="['fal', 'angle-right']"/></div>
</div>
</template>

Expand All @@ -10,7 +12,33 @@ import Vue from 'vue';
import anime from 'animejs';
export default Vue.extend({
props: ['image'],
props: {
images: {
type: Array,
required: true
},
index: {
type: Number,
required: true
}
},
data() {
return {
i: this.index,
queue: null
};
},
computed: {
image() {
return this.images[this.i];
},
keymap() {
return {
'left': this.left,
'right': this.right
};
}
},
mounted() {
anime({
targets: this.$el,
Expand All @@ -20,6 +48,67 @@ export default Vue.extend({
});
},
methods: {
left() {
if (this.queue) {
this.queue.push(true);
} else {
this.queue = [];
this.shift(true);
}
},
right() {
if (this.queue) {
this.queue.push(false);
} else {
this.queue = [];
this.shift(false);
}
},
shift(isLeft: boolean, continued = false) {
const self = this;
const targets = this.$refs.rotator;
anime({
targets,
duration: continued ? 30 : 300,
rotateY: isLeft ? 90 : -90,
easing: continued ? 'linear' : 'easeInSine',
complete() {
self.i = isLeft ? self.i ? --self.i : ~-self.images.length : ++self.i % self.images.length;
anime({
targets,
duration: 0,
rotateY: isLeft ? -90 : 90,
easing: 'linear',
complete() {
const stack = self.queue.shift();
const continues = stack !== undefined;
anime({
targets,
duration: continues ? 30 : 300,
rotateY: 0,
easing: continues ? 'linear' : 'easeOutSine',
complete() {
if (continues) {
self.shift(stack, true);
} else {
const stack = self.queue.shift();
if (stack === undefined) {
self.queue = null;
} else {
self.shift(stack);
}
}
}
})
}
})
}
});
},
close() {
anime({
targets: this.$el,
Expand All @@ -35,17 +124,16 @@ export default Vue.extend({

<style lang="stylus" scoped>
.dkjvrdxtkvqrwmhfickhndpmnncsgacq
display block
position fixed
z-index 2048
top 0
left 0
width 100%
height 100%
opacity 0
perspective 100vw
> .bg
display block
position fixed
z-index 1
top 0
Expand All @@ -66,4 +154,37 @@ export default Vue.extend({
margin auto
cursor zoom-out
image-orientation from-image
transform-style preserve-3d
> .paginator
align-items center
background var(--text)
color var(--bg)
display flex
height 10vw
justify-content center
margin -5vw 0 0
opacity .25
position fixed
top 50%
width 5vw
z-index 3
> svg
height 4vw
width 1.5vw
&.left
border-radius 0 100% 100% 0 / 50%
left 0
> svg
margin 0 .5vw 0 0
&.right
border-radius 100% 0 0 100% / 50%
right 0
> svg
margin 0 0 0 .5vw
</style>
16 changes: 12 additions & 4 deletions src/client/app/common/views/components/media-image-legacy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url'
export default Vue.extend({
i18n: i18n('common/views/components/media-image.vue'),
props: {
image: {
type: Object,
images: {
type: Array,
required: true
},
index: {
type: Number,
required: true
},
raw: {
Expand All @@ -36,8 +40,11 @@ export default Vue.extend({
return {
hide: true
};
}
},
computed: {
image(): object {
return this.images[this.index];
},
style(): any {
let url = `url(${
this.$store.state.device.disableShowingAnimatedImages
Expand All @@ -60,7 +67,8 @@ export default Vue.extend({
methods: {
onClick() {
this.$root.new(ImageViewer, {
image: this.image
images: this.images,
index: this.index
});
}
}
Expand Down
16 changes: 12 additions & 4 deletions src/client/app/common/views/components/media-image.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ import { getStaticImageUrl } from '../../../common/scripts/get-static-image-url'
export default Vue.extend({
i18n: i18n('common/views/components/media-image.vue'),
props: {
image: {
type: Object,
images: {
type: Array,
required: true
},
index: {
type: Number,
required: true
},
raw: {
Expand All @@ -40,8 +44,11 @@ export default Vue.extend({
return {
hide: true
};
}
},
computed: {
image(): object {
return this.images[this.index];
},
src(): string {
return this.$store.state.device.disableShowingAnimatedImages
? getStaticImageUrl(this.image.thumbnailUrl)
Expand All @@ -59,7 +66,8 @@ export default Vue.extend({
methods: {
onClick() {
this.$root.new(ImageViewer, {
image: this.image
images: this.images,
index: this.index
});
}
}
Expand Down
26 changes: 19 additions & 7 deletions src/client/app/common/views/components/media-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
</template>
<div v-if="count" class="grid-container" ref="container">
<div :data-count="count" ref="grid">
<template v-for="media in mediaList">
<mk-media-video v-if="media.type.startsWith('video')" :video="media" :key="media.id"/>
<x-image v-else-if="media.type.startsWith('image') && $store.state.settings.dynamicView" :image="media" :key="media.id" :raw="raw" :count="count"/>
<x-image-legacy v-else-if="media.type.startsWith('image')" :image="media" :key="media.id" :raw="raw" :count="count"/>
<template v-for="(media, i) in mediaList">
<mk-media-video v-if="isVideo(media)" :video="media" :key="media.id"/>
<x-image v-else-if="isImage(media) && $store.state.settings.dynamicView" :images="images" :index="i - [...mediaList].splice(0, i).filter(isVideo).length" :key="media.id" :raw="raw" :count="count"/>
<x-image-legacy v-else-if="isImage(media)" :images="images" :index="i - [...mediaList].splice(0, i).filter(isVideo).length" :key="media.id" :raw="raw" :count="count"/>
</template>
</div>
</div>
Expand Down Expand Up @@ -39,8 +39,14 @@ export default Vue.extend({
}
},
computed: {
images(): unknown[] {
return (this.mediaList as { type: string }[]).filter(this.isImage);
},
videos(): unknown[] {
return (this.mediaList as { type: string }[]).filter(this.isVideo);
},
count(): number {
return this.mediaList.filter(this.previewable).length;
return (this.mediaList as { type: string }[]).filter(this.previewable).length;
}
},
mounted() {
Expand Down Expand Up @@ -69,8 +75,14 @@ export default Vue.extend({
//#endregion
},
methods: {
previewable(file) {
return file.type.startsWith('video') || file.type.startsWith('image');
isImage(file: { type: string }) {
return file.type.startsWith('image');
},
isVideo(file: { type: string }) {
return file.type.startsWith('video');
},
previewable(file: { type: string }) {
return this.isImage(file) || this.isVideo(file);
}
}
});
Expand Down

0 comments on commit d08c712

Please sign in to comment.