mirror of
https://github.com/kokonect-link/cherrypick
synced 2025-01-24 02:34:00 +09:00
Merge branch 'develop' of https://github.com/kokonect-link/cherrypick into develop
This commit is contained in:
commit
ebdb65b188
@ -4,38 +4,44 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="files.files.length > 0" :class="[$style.root, $style.visible]">
|
||||
<div v-if="files.files[0].isSensitive && !showingFiles.includes(files.files[0].id)" :key="files.id + files.files[0].id" :class="$style.img" @click="showingFiles.push(files.files[0].id)">
|
||||
<div v-if="note.files.length > 0" :class="[$style.root, $style.visible]">
|
||||
<div v-if="!showingFiles.includes(note.files[0].id)" :key="note.id + note.files[0].id" :class="$style.img" @click="onClick($event,note.files[0])" @dblclick="onDblClick(note.files[0])">
|
||||
<!-- TODO: 画像以外のファイルに対応 -->
|
||||
<ImgWithBlurhash :class="$style.sensitiveImg" :hash="files.files[0].blurhash" :src="thumbnail(files.files[0])" :title="files.files[0].name" :forceBlurhash="true"/>
|
||||
<ImgWithBlurhash :class="$style.sensitiveImg" :hash="note.files[0].blurhash" :src="thumbnail(note.files[0])" :title="note.files[0].name" :forceBlurhash="true"/>
|
||||
<div :class="$style.sensitive">
|
||||
<div>
|
||||
<div><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}</div>
|
||||
<div v-if="note.files[0].isSensitive" style="display: block;"><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}{{ defaultStore.state.dataSaver.media ? ` (${i18n.ts.image}${note.files[0].size ? ' ' + bytes(note.files[0].size) : ''})` : '' }}</div>
|
||||
<div v-else style="display: block;"><i class="ti ti-photo"></i> {{ defaultStore.state.dataSaver.media && note.files[0].size ? bytes(note.files[0].size) : i18n.ts.image }}</div>
|
||||
<div>{{ i18n.ts.clickToShow }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MkA v-else :class="[$style.img, { [$style.multipleImg]: files.files.length > 1 }]" :to="notePage(files)">
|
||||
<MkA v-else :class="[$style.img, { [$style.multipleImg]: note.files.length > 1 }]" :to="notePage(note)">
|
||||
<!-- TODO: 画像以外のファイルに対応 -->
|
||||
<ImgWithBlurhash
|
||||
:hash="files.files[0].blurhash"
|
||||
:src="thumbnail(files.files[0])"
|
||||
:title="files.files[0].name"
|
||||
:hash="note.files[0].blurhash"
|
||||
:src="thumbnail(note.files[0])"
|
||||
:title="note.files[0].name"
|
||||
@mouseover="defaultStore.state.showingAnimatedImages === 'interaction' ? playAnimation = true : ''"
|
||||
@mouseout="defaultStore.state.showingAnimatedImages === 'interaction' ? playAnimation = false : ''"
|
||||
@touchstart="defaultStore.state.showingAnimatedImages === 'interaction' ? playAnimation = true : ''"
|
||||
@touchend="defaultStore.state.showingAnimatedImages === 'interaction' ? playAnimation = false : ''"
|
||||
/>
|
||||
<div :class="$style.indicators">
|
||||
<div v-if="['image/gif'].includes(note.files[0].type)" :class="$style.indicator">GIF</div>
|
||||
<div v-if="['image/apng'].includes(note.files[0].type)" :class="$style.indicator">APNG</div>
|
||||
<div v-if="note.files[0].isSensitive" :class="$style.indicator" style="color: var(--MI_THEME-warn);" :title="i18n.ts.sensitive"><i class="ti ti-eye-exclamation"></i></div>
|
||||
</div>
|
||||
</MkA>
|
||||
<div v-if="files.files.length > 1" :class="$style.multiple">
|
||||
<span style="text-align: center; margin-right: 0.25em;">{{ files.files.length }}</span>
|
||||
<div v-if="note.files.length > 1" :class="$style.multiple">
|
||||
<span style="text-align: center; margin-right: 0.25em;">{{ note.files.length }}</span>
|
||||
<i class="ti ti-box-multiple-filled"></i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref } from 'vue';
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import * as Misskey from 'cherrypick-js';
|
||||
import { getStaticImageUrl } from '@/scripts/media-proxy.js';
|
||||
import { notePage } from '@/filters/note.js';
|
||||
@ -43,10 +49,13 @@ import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
|
||||
import MkA from '@/components/global/MkA.vue';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import MkRippleEffect from '@/components/MkRippleEffect.vue';
|
||||
import * as os from '@/os.js';
|
||||
import bytes from '@/filters/bytes.js';
|
||||
|
||||
const props = defineProps<{
|
||||
user: Misskey.entities.UserDetailed;
|
||||
files: Misskey.entities.DriveFile[];
|
||||
note: Misskey.entities.Note & { files:Misskey.entities.DriveFile[] };
|
||||
}>();
|
||||
|
||||
const showingFiles = ref<string[]>([]);
|
||||
@ -61,6 +70,52 @@ function thumbnail(image: Misskey.entities.DriveFile): string | null {
|
||||
: image.thumbnailUrl;
|
||||
}
|
||||
|
||||
async function onClick(ev: MouseEvent, image:Misskey.entities.DriveFile) {
|
||||
if (!showingFiles.value.includes(image.id)) {
|
||||
ev.stopPropagation();
|
||||
if (image.isSensitive && defaultStore.state.confirmWhenRevealingSensitiveMedia) {
|
||||
const { canceled } = await os.confirm({
|
||||
type: 'question',
|
||||
text: i18n.ts.sensitiveMediaRevealConfirm,
|
||||
});
|
||||
if (canceled) return;
|
||||
showingFiles.value.push(image.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultStore.state.nsfwOpenBehavior === 'doubleClick') os.popup(MkRippleEffect, { x: ev.clientX, y: ev.clientY }, {});
|
||||
if (defaultStore.state.nsfwOpenBehavior === 'click') showingFiles.value.push(image.id);
|
||||
}
|
||||
|
||||
async function onDblClick(image:Misskey.entities.DriveFile) {
|
||||
if (!showingFiles.value.includes(image.id) && defaultStore.state.nsfwOpenBehavior === 'doubleClick') showingFiles.value.push(image.id);
|
||||
}
|
||||
|
||||
watch(() => props.note, () => {
|
||||
if (defaultStore.state.nsfw === 'force' || defaultStore.state.dataSaver.media) {
|
||||
//hide = true;
|
||||
} else {
|
||||
for (const image of props.note.files) {
|
||||
if (image.isSensitive) {
|
||||
if (defaultStore.state.nsfw !== 'ignore') {
|
||||
//hide = true;
|
||||
} else {
|
||||
if (!showingFiles.value.includes(image.id)) {
|
||||
showingFiles.value.push(image.id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!showingFiles.value.includes(image.id)) {
|
||||
showingFiles.value.push(image.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
deep: true,
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
function resetTimer() {
|
||||
playAnimation.value = true;
|
||||
clearTimeout(playAnimationTimer);
|
||||
@ -119,11 +174,16 @@ onUnmounted(() => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
place-items: center;
|
||||
font-size: 0.8em;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.sensitive > div{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.visible {
|
||||
position: relative;
|
||||
@ -160,6 +220,48 @@ html[data-color-scheme=light] .visible {
|
||||
filter: drop-shadow(0 0 1.5px #6060608a);
|
||||
}
|
||||
|
||||
.indicators {
|
||||
display: inline-flex;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
pointer-events: none;
|
||||
opacity: .5;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
/* Hardcode to black because either --MI_THEME-bg or --MI_THEME-fg makes it hard to read in dark/light mode */
|
||||
background-color: black;
|
||||
border-radius: 6px;
|
||||
color: var(--MI_THEME-accentLighten);
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
.indicators {
|
||||
display: inline-flex;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
pointer-events: none;
|
||||
opacity: .5;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
/* Hardcode to black because either --MI_THEME-bg or --MI_THEME-fg makes it hard to read in dark/light mode */
|
||||
background-color: black;
|
||||
border-radius: 6px;
|
||||
color: var(--MI_THEME-accentLighten);
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
@container (max-width: 785px) {
|
||||
.img {
|
||||
height: 192px;
|
||||
|
@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
<template #default="{ items: user }">
|
||||
<div :class="$style.stream">
|
||||
<XFiles v-for="item in user" :key="item.user.id" :user="item.user" :files="item"/>
|
||||
<XFiles v-for="item in user" :key="item.user.id" :user="item.user" :note="item"/>
|
||||
</div>
|
||||
</template>
|
||||
</MkPagination>
|
||||
|
Loading…
Reference in New Issue
Block a user