Added Preview images for non image files (Based on type / generated from extension)
Closes #31
This commit is contained in:
		@@ -1,31 +0,0 @@
 | 
			
		||||
<script setup async lang="ts">
 | 
			
		||||
import type { TokenInjectType } from '@/api';
 | 
			
		||||
import { inject, ref } from 'vue';
 | 
			
		||||
import { NImage } from 'naive-ui';
 | 
			
		||||
import { check_token, FS, isErrorResponse } from '@/api';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	alt: string;
 | 
			
		||||
	id: number;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;
 | 
			
		||||
 | 
			
		||||
const success = ref(false);
 | 
			
		||||
const data = ref('');
 | 
			
		||||
 | 
			
		||||
const token = await check_token(jwt);
 | 
			
		||||
if (token) {
 | 
			
		||||
	const resp = await FS.download_preview(jwt.jwt.value ?? '', props.id);
 | 
			
		||||
	if (!isErrorResponse(resp)) {
 | 
			
		||||
		data.value = resp.data;
 | 
			
		||||
		success.value = true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
	<NImage v-if="success" :alt="alt" :src="data" />
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style lang="scss"></style>
 | 
			
		||||
@@ -34,7 +34,7 @@ import {
 | 
			
		||||
	Download
 | 
			
		||||
} from '@vicons/carbon';
 | 
			
		||||
import NLink from '@/components/NLink.vue';
 | 
			
		||||
import AsyncImage from '@/components/AsyncImage.vue';
 | 
			
		||||
import PreviewImage from '@/components/DirViewer/PreviewImage.vue';
 | 
			
		||||
import createZipDialog from '@/components/DirViewer/CreateZipDialog';
 | 
			
		||||
import DeleteModal from '@/components/DirViewer/DeleteModal.vue';
 | 
			
		||||
 | 
			
		||||
@@ -219,12 +219,10 @@ const previewColumns: DataTableColumn<Responses.GetNodeEntry>[] = [
 | 
			
		||||
		title: 'Preview',
 | 
			
		||||
		key: 'preview',
 | 
			
		||||
		render(node) {
 | 
			
		||||
			return node.preview ? (
 | 
			
		||||
			return node.isFile ? (
 | 
			
		||||
				<Suspense>
 | 
			
		||||
					{{
 | 
			
		||||
						default: () => (
 | 
			
		||||
							<AsyncImage alt={node.name} id={node.id} />
 | 
			
		||||
						),
 | 
			
		||||
						default: () => <PreviewImage node={node} />,
 | 
			
		||||
						fallback: () => <NSpin size="small" />
 | 
			
		||||
					}}
 | 
			
		||||
				</Suspense>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								frontend/src/components/DirViewer/PreviewImage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								frontend/src/components/DirViewer/PreviewImage.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
<script setup async lang="ts">
 | 
			
		||||
import type { TokenInjectType } from '@/api';
 | 
			
		||||
import { inject, ref } from 'vue';
 | 
			
		||||
import { NImage, NIcon } from 'naive-ui';
 | 
			
		||||
import { Image, Music, Video, Document } from '@vicons/carbon';
 | 
			
		||||
import { check_token, FS, isErrorResponse, Responses } from '@/api';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	node: Responses.GetNodeEntry;
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
enum fileTypes {
 | 
			
		||||
	UNKNOWN,
 | 
			
		||||
	IMAGE,
 | 
			
		||||
	AUDIO,
 | 
			
		||||
	VIDEO,
 | 
			
		||||
	PDF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const jwt = inject<TokenInjectType>('jwt') as TokenInjectType;
 | 
			
		||||
 | 
			
		||||
const success = ref(false);
 | 
			
		||||
const data = ref('');
 | 
			
		||||
const fileType = ref<fileTypes>(fileTypes.UNKNOWN);
 | 
			
		||||
 | 
			
		||||
const token = await check_token(jwt);
 | 
			
		||||
if (token) {
 | 
			
		||||
	if (props.node.preview) {
 | 
			
		||||
		const resp = await FS.download_preview(token, props.node.id);
 | 
			
		||||
		if (!isErrorResponse(resp)) {
 | 
			
		||||
			data.value = resp.data;
 | 
			
		||||
			success.value = true;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		fileType.value = fileTypes.UNKNOWN;
 | 
			
		||||
		const resp = await FS.get_type(token, props.node.id);
 | 
			
		||||
		if (!isErrorResponse(resp)) {
 | 
			
		||||
			if (resp.type.startsWith('image')) fileType.value = fileTypes.IMAGE;
 | 
			
		||||
			else if (resp.type.startsWith('application/pdf'))
 | 
			
		||||
				fileType.value = fileTypes.PDF;
 | 
			
		||||
			else if (resp.type.startsWith('audio'))
 | 
			
		||||
				fileType.value = fileTypes.AUDIO;
 | 
			
		||||
			else if (resp.type.startsWith('video'))
 | 
			
		||||
				fileType.value = fileTypes.VIDEO;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
	<n-image v-if="success" :alt="node.name" :src="data" />
 | 
			
		||||
	<n-icon v-else-if="fileType !== fileTypes.UNKNOWN" size="2em">
 | 
			
		||||
		<Image v-if="fileType === fileTypes.IMAGE" />
 | 
			
		||||
		<Music v-else-if="fileType === fileTypes.AUDIO" />
 | 
			
		||||
		<Video v-else-if="fileType === fileTypes.VIDEO" />
 | 
			
		||||
		<Document v-else-if="fileType === fileTypes.PDF" />
 | 
			
		||||
	</n-icon>
 | 
			
		||||
	<svg
 | 
			
		||||
		v-else
 | 
			
		||||
		viewBox="0 0 32 32"
 | 
			
		||||
		xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
		height="2em"
 | 
			
		||||
	>
 | 
			
		||||
		<path
 | 
			
		||||
			d="M22 14v-4a.91.91 0 0 0-.3-.7l-7-7A.909.909 0 0 0 14 2H4a2.006 2.006 0 0 0-2 2v24a2 2 0 0 0 2 2h16v-2H4V4h8v6a2.006 2.006 0 0 0 2 2h6v2zm-8-4V4.4l5.6 5.6z"
 | 
			
		||||
			fill="currentColor"
 | 
			
		||||
		/>
 | 
			
		||||
		<text
 | 
			
		||||
			transform="matrix(4,0,0,1.9,3.5,11.25)"
 | 
			
		||||
			font-family="'Myriad Pro'"
 | 
			
		||||
			font-size="8px"
 | 
			
		||||
			lengthAdjust="spacingAndGlyphs"
 | 
			
		||||
			textLength="6"
 | 
			
		||||
			xml:space="preserve"
 | 
			
		||||
			fill="currentColor"
 | 
			
		||||
		>
 | 
			
		||||
			<tspan x="0.4" y="7.5">
 | 
			
		||||
				{{ node.name.split('.').pop().toUpperCase() }}
 | 
			
		||||
			</tspan>
 | 
			
		||||
		</text>
 | 
			
		||||
	</svg>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style lang="scss"></style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user