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)
|
## 12.x.x (unreleased)
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
|
- クライアント: 画像ビューアを強化
|
||||||
- クライアント: メンションにユーザーのアバターを表示するように
|
- クライアント: メンションにユーザーのアバターを表示するように
|
||||||
- クライアント: デザインの調整
|
- クライアント: デザインの調整
|
||||||
- クライアント: twemojiをセルフホスティングするように
|
- クライアント: twemojiをセルフホスティングするように
|
||||||
|
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
|
- クライアント: CWで画像が隠されたとき、画像の高さがおかしいことになる問題を修正
|
||||||
|
|
||||||
|
### NOTE
|
||||||
|
- このバージョンから、iOS 15未満のサポートがされなくなります。対象のバージョンをお使いの方は、iOSのバージョンアップを行ってください。
|
||||||
|
|
||||||
## 12.93.2 (2021/10/23)
|
## 12.93.2 (2021/10/23)
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
"os-utils": "0.0.14",
|
"os-utils": "0.0.14",
|
||||||
"parse5": "6.0.1",
|
"parse5": "6.0.1",
|
||||||
"pg": "8.7.1",
|
"pg": "8.7.1",
|
||||||
|
"photoswipe": "git://github.com/dimsemenov/photoswipe#v5-beta",
|
||||||
"portscanner": "2.2.0",
|
"portscanner": "2.2.0",
|
||||||
"postcss": "8.3.11",
|
"postcss": "8.3.11",
|
||||||
"postcss-loader": "6.2.0",
|
"postcss-loader": "6.2.0",
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
<a
|
<a
|
||||||
:href="image.url"
|
:href="image.url"
|
||||||
:title="image.name"
|
:title="image.name"
|
||||||
@click.prevent="onClick"
|
|
||||||
>
|
>
|
||||||
<ImgWithBlurhash :hash="image.blurhash" :src="url" :alt="image.comment" :title="image.comment" :cover="false"/>
|
<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>
|
<div class="gif" v-if="image.type === 'image/gif'">GIF</div>
|
||||||
|
@ -73,17 +72,6 @@ export default defineComponent({
|
||||||
immediate: true,
|
immediate: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
onClick() {
|
|
||||||
if (this.$store.state.imageNewTab) {
|
|
||||||
window.open(this.image.url, '_blank');
|
|
||||||
} else {
|
|
||||||
os.popup(ImageViewer, {
|
|
||||||
image: this.image
|
|
||||||
}, {}, 'closed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mk-media-list">
|
<div class="hoawjimk">
|
||||||
<XBanner v-for="media in mediaList.filter(media => !previewable(media))" :media="media" :key="media.id"/>
|
<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 v-if="mediaList.filter(media => previewable(media)).length > 0" class="gird-container">
|
||||||
<div :data-count="mediaList.filter(media => previewable(media)).length" :style="gridInnerStyle">
|
<div :data-count="mediaList.filter(media => previewable(media)).length" ref="gallery">
|
||||||
<template v-for="media in mediaList">
|
<template v-for="media in mediaList">
|
||||||
<XVideo :video="media" :key="media.id" v-if="media.type.startsWith('video')"/>
|
<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>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,11 +13,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<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 XBanner from './media-banner.vue';
|
||||||
import XImage from './media-image.vue';
|
import XImage from './media-image.vue';
|
||||||
import XVideo from './media-video.vue';
|
import XVideo from './media-video.vue';
|
||||||
import * as os from '@client/os';
|
import * as os from '@client/os';
|
||||||
|
import { defaultStore } from '@client/store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -27,63 +32,65 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
mediaList: {
|
mediaList: {
|
||||||
required: true
|
type: Array as PropType<misskey.entities.DriveFile[]>,
|
||||||
|
required: true,
|
||||||
},
|
},
|
||||||
raw: {
|
raw: {
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
setup(props) {
|
||||||
return {
|
const gallery = ref(null);
|
||||||
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;
|
|
||||||
|
|
||||||
this.sizeWaiting = true;
|
onMounted(() => {
|
||||||
|
const lightbox = new PhotoSwipeLightbox({
|
||||||
window.requestAnimationFrame(() => {
|
dataSource: props.mediaList.filter(media => media.type.startsWith('image')).map(media => ({
|
||||||
this.sizeWaiting = false;
|
src: media.url,
|
||||||
|
w: media.properties.width,
|
||||||
if (this.$refs.gridOuter) {
|
h: media.properties.height,
|
||||||
let height = 287;
|
alt: media.name,
|
||||||
const parent = this.$parent.$el;
|
})),
|
||||||
|
gallery: gallery.value,
|
||||||
if (this.$refs.gridOuter.clientHeight) {
|
children: '.image',
|
||||||
height = this.$refs.gridOuter.clientHeight;
|
thumbSelector: '.image',
|
||||||
} else if (parent) {
|
pswpModule: PhotoSwipe
|
||||||
height = parent.getBoundingClientRect().width * 9 / 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.gridInnerStyle = { height: `${height}px` };
|
|
||||||
} else {
|
|
||||||
this.gridInnerStyle = {};
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.mk-media-list {
|
.hoawjimk {
|
||||||
> .gird-container {
|
> .gird-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -8271,6 +8271,10 @@ pgpass@1.x:
|
||||||
dependencies:
|
dependencies:
|
||||||
split "^1.0.0"
|
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:
|
picocolors@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||||
|
|
Loading…
Reference in a new issue