diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-25 02:28:18 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-25 02:28:18 +0900 |
| commit | e52a9e0a6529a9c739c5237c165b68861a9390dc (patch) | |
| tree | e47587871cdcfa00a3f921643d7531d681548b4b /src | |
| parent | :art: (diff) | |
| download | misskey-e52a9e0a6529a9c739c5237c165b68861a9390dc.tar.gz misskey-e52a9e0a6529a9c739c5237c165b68861a9390dc.tar.bz2 misskey-e52a9e0a6529a9c739c5237c165b68861a9390dc.zip | |
feat(client): Improve image viewer
Resolve #7545
Resolve #6811
Close #7808
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/components/media-image.vue | 12 | ||||
| -rw-r--r-- | src/client/components/media-list.vue | 99 |
2 files changed, 53 insertions, 58 deletions
diff --git a/src/client/components/media-image.vue b/src/client/components/media-image.vue index 863eb10272..fd5e0b5f9b 100644 --- a/src/client/components/media-image.vue +++ b/src/client/components/media-image.vue @@ -12,7 +12,6 @@ <a :href="image.url" :title="image.name" - @click.prevent="onClick" > <ImgWithBlurhash :hash="image.blurhash" :src="url" :alt="image.comment" :title="image.comment" :cover="false"/> <div class="gif" v-if="image.type === 'image/gif'">GIF</div> @@ -73,17 +72,6 @@ export default defineComponent({ immediate: true, }); }, - methods: { - onClick() { - if (this.$store.state.imageNewTab) { - window.open(this.image.url, '_blank'); - } else { - os.popup(ImageViewer, { - image: this.image - }, {}, 'closed'); - } - } - } }); </script> diff --git a/src/client/components/media-list.vue b/src/client/components/media-list.vue index 71767a0f9f..c1ec6147f1 100644 --- a/src/client/components/media-list.vue +++ b/src/client/components/media-list.vue @@ -1,11 +1,11 @@ <template> -<div class="mk-media-list"> +<div class="hoawjimk"> <XBanner v-for="media in mediaList.filter(media => !previewable(media))" :media="media" :key="media.id"/> - <div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container" ref="gridOuter"> - <div :data-count="mediaList.filter(media => previewable(media)).length" :style="gridInnerStyle"> + <div v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container"> + <div :data-count="mediaList.filter(media => previewable(media)).length" ref="gallery"> <template v-for="media in mediaList"> <XVideo :video="media" :key="media.id" v-if="media.type.startsWith('video')"/> - <XImage :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/> + <XImage class="image" :data-id="media.id" :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/> </template> </div> </div> @@ -13,11 +13,16 @@ </template> <script lang="ts"> -import { defineComponent } from 'vue'; +import { defineComponent, onMounted, PropType, ref } from 'vue'; +import * as misskey from 'misskey-js'; +import PhotoSwipeLightbox from 'photoswipe/dist/photoswipe-lightbox.esm.js'; +import PhotoSwipe from 'photoswipe/dist/photoswipe.esm.js'; +import 'photoswipe/dist/photoswipe.css'; import XBanner from './media-banner.vue'; import XImage from './media-image.vue'; import XVideo from './media-video.vue'; import * as os from '@client/os'; +import { defaultStore } from '@client/store'; export default defineComponent({ components: { @@ -27,63 +32,65 @@ export default defineComponent({ }, props: { mediaList: { - required: true + type: Array as PropType<misskey.entities.DriveFile[]>, + required: true, }, raw: { default: false }, }, - data() { - return { - gridInnerStyle: {}, - sizeWaiting: false - } - }, - mounted() { - this.size(); - window.addEventListener('resize', this.size); - }, - beforeUnmount() { - window.removeEventListener('resize', this.size); - }, - activated() { - this.size(); - }, - methods: { - previewable(file) { - return file.type.startsWith('video') || file.type.startsWith('image'); - }, - size() { - // for Safari bug - if (this.sizeWaiting) return; + setup(props) { + const gallery = ref(null); - this.sizeWaiting = true; + onMounted(() => { + const lightbox = new PhotoSwipeLightbox({ + dataSource: props.mediaList.filter(media => media.type.startsWith('image')).map(media => ({ + src: media.url, + w: media.properties.width, + h: media.properties.height, + alt: media.name, + })), + gallery: gallery.value, + children: '.image', + thumbSelector: '.image', + pswpModule: PhotoSwipe + }); - window.requestAnimationFrame(() => { - this.sizeWaiting = false; + lightbox.on('itemData', (e) => { + const { itemData } = e; - if (this.$refs.gridOuter) { - let height = 287; - const parent = this.$parent.$el; + // element is children + const { element } = itemData; - if (this.$refs.gridOuter.clientHeight) { - height = this.$refs.gridOuter.clientHeight; - } else if (parent) { - height = parent.getBoundingClientRect().width * 9 / 16; - } + console.log(element); - this.gridInnerStyle = { height: `${height}px` }; - } else { - this.gridInnerStyle = {}; - } + const id = element.dataset.id; + const file = props.mediaList.find(media => media.id === id); + + itemData.src = file.url; + itemData.w = Number(file.properties.width); + itemData.h = Number(file.properties.height); + itemData.msrc = file.thumbnailUrl; + itemData.thumbCropped = true; }); - } + + lightbox.init(); + }); + + const previewable = (file: misskey.entities.DriveFile): boolean => { + return file.type.startsWith('video') || file.type.startsWith('image'); + }; + + return { + previewable, + gallery, + }; }, }); </script> <style lang="scss" scoped> -.mk-media-list { +.hoawjimk { > .gird-container { position: relative; width: 100%; |