feat(client): Improve image viewer
Resolve #7545 Resolve #6811 Close #7808
This commit is contained in:
parent
67bf6ff3ce
commit
e52a9e0a65
5 changed files with 67 additions and 62 deletions
|
@ -10,11 +10,16 @@
|
|||
## 12.x.x (unreleased)
|
||||
|
||||
### Improvements
|
||||
- クライアント: 画像ビューアを強化
|
||||
- クライアント: メンションにユーザーのアバターを表示するように
|
||||
- クライアント: デザインの調整
|
||||
- クライアント: twemojiをセルフホスティングするように
|
||||
|
||||
### Bugfixes
|
||||
- クライアント: CWで画像が隠されたとき、画像の高さがおかしいことになる問題を修正
|
||||
|
||||
### NOTE
|
||||
- このバージョンから、iOS 15未満のサポートがされなくなります。対象のバージョンをお使いの方は、iOSのバージョンアップを行ってください。
|
||||
|
||||
## 12.93.2 (2021/10/23)
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
"os-utils": "0.0.14",
|
||||
"parse5": "6.0.1",
|
||||
"pg": "8.7.1",
|
||||
"photoswipe": "git://github.com/dimsemenov/photoswipe#v5-beta",
|
||||
"portscanner": "2.2.0",
|
||||
"postcss": "8.3.11",
|
||||
"postcss-loader": "6.2.0",
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
window.requestAnimationFrame(() => {
|
||||
this.sizeWaiting = false;
|
||||
|
||||
if (this.$refs.gridOuter) {
|
||||
let height = 287;
|
||||
const parent = this.$parent.$el;
|
||||
|
||||
if (this.$refs.gridOuter.clientHeight) {
|
||||
height = this.$refs.gridOuter.clientHeight;
|
||||
} else if (parent) {
|
||||
height = parent.getBoundingClientRect().width * 9 / 16;
|
||||
}
|
||||
|
||||
this.gridInnerStyle = { height: `${height}px` };
|
||||
} else {
|
||||
this.gridInnerStyle = {};
|
||||
}
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
lightbox.on('itemData', (e) => {
|
||||
const { itemData } = e;
|
||||
|
||||
// element is children
|
||||
const { element } = itemData;
|
||||
|
||||
console.log(element);
|
||||
|
||||
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%;
|
||||
|
|
|
@ -8271,6 +8271,10 @@ pgpass@1.x:
|
|||
dependencies:
|
||||
split "^1.0.0"
|
||||
|
||||
"photoswipe@git://github.com/dimsemenov/photoswipe#v5-beta":
|
||||
version "5.1.7"
|
||||
resolved "git://github.com/dimsemenov/photoswipe#60040164333bd257409669e715e4327afdb3aec7"
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
|
|
Loading…
Reference in a new issue