summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2021-10-25 02:28:18 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2021-10-25 02:28:18 +0900
commite52a9e0a6529a9c739c5237c165b68861a9390dc (patch)
treee47587871cdcfa00a3f921643d7531d681548b4b /src
parent:art: (diff)
downloadmisskey-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.vue12
-rw-r--r--src/client/components/media-list.vue99
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%;