From 091923764d3083dda958ca1109c6c7a806414a4f Mon Sep 17 00:00:00 2001 From: syuilo <Syuilotan@yahoo.co.jp> Date: Sun, 16 Feb 2020 22:46:18 +0900 Subject: [PATCH] Implement image dialog --- CHANGELOG.md | 1 + locales/ja-JP.yml | 1 + src/client/components/image-viewer.vue | 54 ++++++++++++++++++++++++++ src/client/components/media-image.vue | 12 +++++- src/client/components/modal.vue | 9 ++++- src/client/pages/settings/general.vue | 6 +++ src/client/store.ts | 1 + 7 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 src/client/components/image-viewer.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index 7207544620..07d836041c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ unreleased ### ✨Improvements * 投稿詳細ページで前後の投稿を見れるように * 自分のfollowersノートはRenoteできるように +* 画像ダイアログを実装 * フォロー申請ページの調整 * 壁紙設定の強化 * 画面が狭い状態でMisskeyを起動した場合でも、画面幅が広がったときにウィジェットを表示するように diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 9d88a13601..b628b91ab0 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -402,6 +402,7 @@ existingAcount: "既存のアカウント" regenerate: "再生成" fontSize: "フォントサイズ" noFollowRequests: "フォロー申請はありません" +openImageInNewTab: "画像を新しいタブで開く" _ago: unknown: "謎" diff --git a/src/client/components/image-viewer.vue b/src/client/components/image-viewer.vue new file mode 100644 index 0000000000..3359b600da --- /dev/null +++ b/src/client/components/image-viewer.vue @@ -0,0 +1,54 @@ +<template> +<x-modal ref="modal" @closed="() => { $emit('closed'); destroyDom(); }"> + <img class="xubzgfga" ref="img" :src="image.url" :alt="image.name" :title="image.name" @click="close" tabindex="-1"/> +</x-modal> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import i18n from '../i18n'; +import XModal from './modal.vue'; + +export default Vue.extend({ + i18n, + + components: { + XModal, + }, + + props: { + image: { + type: Object, + required: true + }, + }, + + mounted() { + this.$nextTick(() => { + this.$refs.img.focus(); + }); + }, + + methods: { + close() { + this.$refs.modal.close(); + }, + } +}); +</script> + +<style lang="scss" scoped> +.xubzgfga { + position: fixed; + z-index: 2; + top: 0; + right: 0; + bottom: 0; + left: 0; + max-width: 100%; + max-height: 100%; + margin: auto; + cursor: zoom-out; + image-orientation: from-image; +} +</style> diff --git a/src/client/components/media-image.vue b/src/client/components/media-image.vue index 5ae167d490..3bb1bda5e2 100644 --- a/src/client/components/media-image.vue +++ b/src/client/components/media-image.vue @@ -20,6 +20,7 @@ import Vue from 'vue'; import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; import i18n from '../i18n'; import { getStaticImageUrl } from '../scripts/get-static-image-url'; +import ImageViewer from './image-viewer.vue'; export default Vue.extend({ i18n, @@ -60,7 +61,16 @@ export default Vue.extend({ }, methods: { onClick() { - window.open(this.image.url, '_blank'); + if (this.$store.state.device.imageNewTab) { + window.open(this.image.url, '_blank'); + } else { + const viewer = this.$root.new(ImageViewer, { + image: this.image + }); + this.$once('hook:beforeDestroy', () => { + viewer.close(); + }); + } } } }); diff --git a/src/client/components/modal.vue b/src/client/components/modal.vue index a48c7154ee..1a9d98a8cc 100644 --- a/src/client/components/modal.vue +++ b/src/client/components/modal.vue @@ -1,5 +1,5 @@ <template> -<div class="mk-modal"> +<div class="mk-modal" v-hotkey.global="keymap"> <transition :name="$store.state.device.animation ? 'bg-fade' : ''" appear> <div class="bg" ref="bg" v-if="show" @click="close()"></div> </transition> @@ -20,6 +20,13 @@ export default Vue.extend({ show: true, }; }, + computed: { + keymap(): any { + return { + 'esc': this.close, + }; + }, + }, methods: { close() { this.show = false; diff --git a/src/client/pages/settings/general.vue b/src/client/pages/settings/general.vue index 6b4825c7a9..5a176c0226 100644 --- a/src/client/pages/settings/general.vue +++ b/src/client/pages/settings/general.vue @@ -19,6 +19,7 @@ <mk-button @click="readAllMessagingMessages">{{ $t('markAsReadAllTalkMessages') }}</mk-button> </div> <div class="_content"> + <mk-switch v-model="imageNewTab">{{ $t('openImageInNewTab') }}</mk-switch> <mk-switch v-model="disableAnimatedMfm">{{ $t('disableAnimatedMfm') }}</mk-switch> <mk-switch v-model="reduceAnimation">{{ $t('reduceUiAnimation') }}</mk-switch> <mk-switch v-model="useOsNativeEmojis"> @@ -96,6 +97,11 @@ export default Vue.extend({ get() { return this.$store.state.device.useOsNativeEmojis; }, set(value) { this.$store.commit('device/set', { key: 'useOsNativeEmojis', value }); } }, + + imageNewTab: { + get() { return this.$store.state.device.imageNewTab; }, + set(value) { this.$store.commit('device/set', { key: 'imageNewTab', value }); } + }, }, watch: { diff --git a/src/client/store.ts b/src/client/store.ts index 13722c1bb8..4ebaa9ba55 100644 --- a/src/client/store.ts +++ b/src/client/store.ts @@ -38,6 +38,7 @@ const defaultDeviceSettings = { theme: 'light', animation: true, animatedMfm: true, + imageNewTab: false, userData: {}, };