mirror of
https://github.com/misskey-dev/misskey.git
synced 2024-12-28 03:40:25 +01:00
サムネイルをMkDriveFileThumbnailに統一
This commit is contained in:
parent
33051f06d5
commit
a01d75ba01
5 changed files with 54 additions and 103 deletions
|
@ -5,13 +5,21 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
ref="thumbnail"
|
:class="[$style.root, {
|
||||||
:class="[
|
[$style.sensitiveHighlight]: highlightWhenSensitive && file.isSensitive,
|
||||||
$style.root,
|
[$style.bgIsPanel]: bgIsPanel,
|
||||||
{ [$style.sensitiveHighlight]: highlightWhenSensitive && file.isSensitive },
|
[$style.large]: large,
|
||||||
]"
|
}]"
|
||||||
>
|
>
|
||||||
<ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.name" :title="file.name" :cover="fit !== 'contain'"/>
|
<ImgWithBlurhash
|
||||||
|
v-if="isThumbnailAvailable"
|
||||||
|
:hash="file.blurhash"
|
||||||
|
:src="file.thumbnailUrl"
|
||||||
|
:alt="file.name"
|
||||||
|
:title="file.name"
|
||||||
|
:cover="fit !== 'contain'"
|
||||||
|
:forceBlurHash="forceBlurhash"
|
||||||
|
/>
|
||||||
<i v-else-if="is === 'image'" class="ti ti-photo" :class="$style.icon"></i>
|
<i v-else-if="is === 'image'" class="ti ti-photo" :class="$style.icon"></i>
|
||||||
<i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i>
|
<i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i>
|
||||||
<i v-else-if="is === 'audio' || is === 'midi'" class="ti ti-file-music" :class="$style.icon"></i>
|
<i v-else-if="is === 'audio' || is === 'midi'" class="ti ti-file-music" :class="$style.icon"></i>
|
||||||
|
@ -34,6 +42,9 @@ const props = defineProps<{
|
||||||
file: Misskey.entities.DriveFile;
|
file: Misskey.entities.DriveFile;
|
||||||
fit: 'cover' | 'contain';
|
fit: 'cover' | 'contain';
|
||||||
highlightWhenSensitive?: boolean;
|
highlightWhenSensitive?: boolean;
|
||||||
|
bgIsPanel?: boolean;
|
||||||
|
forceBlurhash?: boolean;
|
||||||
|
large?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const is = computed(() => {
|
const is = computed(() => {
|
||||||
|
@ -60,7 +71,7 @@ const is = computed(() => {
|
||||||
|
|
||||||
const isThumbnailAvailable = computed(() => {
|
const isThumbnailAvailable = computed(() => {
|
||||||
return props.file.thumbnailUrl
|
return props.file.thumbnailUrl
|
||||||
? (is.value === 'image' as const || is.value === 'video')
|
? (is.value === 'image' || is.value === 'video')
|
||||||
: false;
|
: false;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -72,6 +83,10 @@ const isThumbnailAvailable = computed(() => {
|
||||||
background: var(--MI_THEME-panel);
|
background: var(--MI_THEME-panel);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
|
|
||||||
|
&.bgIsPanel {
|
||||||
|
background: var(--MI_THEME-bg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sensitiveHighlight::after {
|
.sensitiveHighlight::after {
|
||||||
|
@ -101,4 +116,8 @@ const isThumbnailAvailable = computed(() => {
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.large .icon {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div :class="[$style.filePreview, { [$style.bgIsPanel]: bgIsPanel }]">
|
|
||||||
<div :class="$style.icon">
|
|
||||||
<i v-if="!FILE_TYPE_BROWSERSAFE.includes(file.type)" class="ti ti-file"></i>
|
|
||||||
<i v-else-if="file.type.startsWith('video/')" class="ti ti-video"></i>
|
|
||||||
<i v-else-if="file.type.startsWith('audio/')" class="ti ti-music"></i>
|
|
||||||
<i v-else class="ti ti-file"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import * as Misskey from 'misskey-js';
|
|
||||||
|
|
||||||
import { FILE_TYPE_BROWSERSAFE } from '@@/js/const.js';
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
file: Misskey.entities.DriveFile;
|
|
||||||
bgIsPanel?: boolean;
|
|
||||||
}>();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" module>
|
|
||||||
.filePreview {
|
|
||||||
background-color: var(--MI_THEME-panel);
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&.bgIsPanel {
|
|
||||||
background-color: var(--MI_THEME-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
> .icon {
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 36px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -7,18 +7,18 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<template v-for="file in note.files">
|
<template v-for="file in note.files">
|
||||||
<div
|
<div
|
||||||
v-if="(defaultStore.state.nsfw === 'force' || file.isSensitive) && defaultStore.state.nsfw !== 'ignore' && !showingFiles.has(file.id)"
|
v-if="(defaultStore.state.nsfw === 'force' || file.isSensitive) && defaultStore.state.nsfw !== 'ignore' && !showingFiles.has(file.id)"
|
||||||
:class="[$style.img, { [$style.square]: square }]"
|
:class="[$style.filePreview, { [$style.square]: square }]"
|
||||||
@click="showingFiles.add(file.id)"
|
@click="showingFiles.add(file.id)"
|
||||||
>
|
>
|
||||||
<ImgWithBlurhash
|
<MkDriveFileThumbnail
|
||||||
v-if="FILE_TYPE_BROWSERSAFE.includes(file.type) && (file.type.startsWith('image/') || (file.type.startsWith('video/') && file.thumbnailUrl != null))"
|
:file="file"
|
||||||
:class="$style.sensitiveImg"
|
fit="cover"
|
||||||
:hash="file.blurhash"
|
:highlightWhenSensitive="defaultStore.state.highlightSensitiveMedia"
|
||||||
:src="thumbnail(file)"
|
|
||||||
:title="file.name"
|
|
||||||
:forceBlurhash="true"
|
:forceBlurhash="true"
|
||||||
|
:large="true"
|
||||||
|
:bgIsPanel="bgIsPanel"
|
||||||
|
:class="$style.file"
|
||||||
/>
|
/>
|
||||||
<XFilePreview v-else :class="$style.sensitiveFile" :file="file" :bgIsPanel="bgIsPanel"/>
|
|
||||||
<div :class="$style.sensitive">
|
<div :class="$style.sensitive">
|
||||||
<div>
|
<div>
|
||||||
<div><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}</div>
|
<div><i class="ti ti-eye-exclamation"></i> {{ i18n.ts.sensitive }}</div>
|
||||||
|
@ -26,30 +26,27 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MkA v-else :class="[$style.img, { [$style.square]: square }]" :to="notePage(note)">
|
<MkA v-else :class="[$style.filePreview, { [$style.square]: square }]" :to="notePage(note)">
|
||||||
<ImgWithBlurhash
|
<MkDriveFileThumbnail
|
||||||
v-if="FILE_TYPE_BROWSERSAFE.includes(file.type) && (file.type.startsWith('image/') || (file.type.startsWith('video/') && file.thumbnailUrl != null))"
|
:file="file"
|
||||||
:hash="file.blurhash"
|
fit="cover"
|
||||||
:src="thumbnail(file)"
|
:highlightWhenSensitive="defaultStore.state.highlightSensitiveMedia"
|
||||||
:title="file.name"
|
:large="true"
|
||||||
|
:bgIsPanel="bgIsPanel"
|
||||||
|
:class="$style.file"
|
||||||
/>
|
/>
|
||||||
<XFilePreview v-else :file="file" :bgIsPanel="bgIsPanel"/>
|
|
||||||
</MkA>
|
</MkA>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { FILE_TYPE_BROWSERSAFE } from '@@/js/const.js';
|
|
||||||
import { notePage } from '@/filters/note.js';
|
import { notePage } from '@/filters/note.js';
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';
|
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { defaultStore } from '@/store.js';
|
import { defaultStore } from '@/store.js';
|
||||||
import { getProxiedImageUrl, getStaticImageUrl } from '@/scripts/media-proxy.js';
|
|
||||||
|
|
||||||
import XFilePreview from '@/components/MkNoteMediaGrid.file.vue';
|
import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
note: Misskey.entities.Note;
|
note: Misskey.entities.Note;
|
||||||
|
@ -58,12 +55,6 @@ defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const showingFiles = ref<Set<string>>(new Set());
|
const showingFiles = ref<Set<string>>(new Set());
|
||||||
|
|
||||||
function thumbnail(image: Misskey.entities.DriveFile): string {
|
|
||||||
return defaultStore.state.disableShowingAnimatedImages
|
|
||||||
? getStaticImageUrl(image.url)
|
|
||||||
: image.thumbnailUrl ?? getProxiedImageUrl(image.url, 'preview');
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" module>
|
<style lang="scss" module>
|
||||||
|
@ -73,10 +64,10 @@ function thumbnail(image: Misskey.entities.DriveFile): string {
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img {
|
.filePreview {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 128px;
|
height: 128px;
|
||||||
border-radius: 6px;
|
border-radius: calc(var(--MI-radius) / 2);
|
||||||
overflow: clip;
|
overflow: clip;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -88,17 +79,10 @@ function thumbnail(image: Misskey.entities.DriveFile): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sensitiveImg {
|
.file {
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
filter: brightness(0.7);
|
border-radius: calc(var(--MI-radius) / 2);
|
||||||
}
|
|
||||||
|
|
||||||
.sensitiveFile {
|
|
||||||
filter: brightness(0.5) blur(2px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sensitive {
|
.sensitive {
|
||||||
|
@ -111,6 +95,8 @@ function thumbnail(image: Misskey.entities.DriveFile): string {
|
||||||
place-items: center;
|
place-items: center;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div :class="$style.root">
|
<div :class="$style.root">
|
||||||
<MkPagination v-slot="{items}" :pagination="pagination">
|
<MkPagination v-slot="{items}" :pagination="pagination">
|
||||||
<div :class="$style.stream">
|
<div :class="$style.stream">
|
||||||
<MkMedias v-for="note in items" :note="note" square/>
|
<MkNoteMediaGrid v-for="note in items" :note="note" square/>
|
||||||
</div>
|
</div>
|
||||||
</MkPagination>
|
</MkPagination>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
|
|
||||||
import MkMedias from '@/components/MkNoteMediaGrid.vue';
|
import MkNoteMediaGrid from '@/components/MkNoteMediaGrid.vue';
|
||||||
import MkPagination from '@/components/MkPagination.vue';
|
import MkPagination from '@/components/MkPagination.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -28,7 +28,7 @@ const props = defineProps<{
|
||||||
|
|
||||||
const pagination = {
|
const pagination = {
|
||||||
endpoint: 'users/notes' as const,
|
endpoint: 'users/notes' as const,
|
||||||
limit: 10,
|
limit: 15,
|
||||||
params: computed(() => ({
|
params: computed(() => ({
|
||||||
userId: props.user.id,
|
userId: props.user.id,
|
||||||
withFiles: true,
|
withFiles: true,
|
||||||
|
@ -44,7 +44,7 @@ const pagination = {
|
||||||
.stream {
|
.stream {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||||
grid-gap: 6px;
|
gap: var(--MI-marginHalf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 600px) {
|
@media screen and (min-width: 600px) {
|
||||||
|
|
|
@ -20,10 +20,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { getProxiedImageUrl, getStaticImageUrl } from '@/scripts/media-proxy.js';
|
|
||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||||
import MkContainer from '@/components/MkContainer.vue';
|
import MkContainer from '@/components/MkContainer.vue';
|
||||||
import { defaultStore } from '@/store.js';
|
|
||||||
import { i18n } from '@/i18n.js';
|
import { i18n } from '@/i18n.js';
|
||||||
import MkNoteMediaGrid from '@/components/MkNoteMediaGrid.vue';
|
import MkNoteMediaGrid from '@/components/MkNoteMediaGrid.vue';
|
||||||
|
|
||||||
|
@ -43,17 +41,11 @@ function unfoldContainer(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function thumbnail(image: Misskey.entities.DriveFile): string {
|
|
||||||
return defaultStore.state.disableShowingAnimatedImages
|
|
||||||
? getStaticImageUrl(image.url)
|
|
||||||
: image.thumbnailUrl ?? getProxiedImageUrl(image.url, 'preview');
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
misskeyApi('users/notes', {
|
misskeyApi('users/notes', {
|
||||||
userId: props.user.id,
|
userId: props.user.id,
|
||||||
withFiles: true,
|
withFiles: true,
|
||||||
limit: 15,
|
limit: 10,
|
||||||
}).then(_notes => {
|
}).then(_notes => {
|
||||||
notes.value = _notes;
|
notes.value = _notes;
|
||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
|
|
Loading…
Reference in a new issue