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
 | 
						Download
 | 
				
			||||||
} from '@vicons/carbon';
 | 
					} from '@vicons/carbon';
 | 
				
			||||||
import NLink from '@/components/NLink.vue';
 | 
					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 createZipDialog from '@/components/DirViewer/CreateZipDialog';
 | 
				
			||||||
import DeleteModal from '@/components/DirViewer/DeleteModal.vue';
 | 
					import DeleteModal from '@/components/DirViewer/DeleteModal.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -219,12 +219,10 @@ const previewColumns: DataTableColumn<Responses.GetNodeEntry>[] = [
 | 
				
			|||||||
		title: 'Preview',
 | 
							title: 'Preview',
 | 
				
			||||||
		key: 'preview',
 | 
							key: 'preview',
 | 
				
			||||||
		render(node) {
 | 
							render(node) {
 | 
				
			||||||
			return node.preview ? (
 | 
								return node.isFile ? (
 | 
				
			||||||
				<Suspense>
 | 
									<Suspense>
 | 
				
			||||||
					{{
 | 
										{{
 | 
				
			||||||
						default: () => (
 | 
											default: () => <PreviewImage node={node} />,
 | 
				
			||||||
							<AsyncImage alt={node.name} id={node.id} />
 | 
					 | 
				
			||||||
						),
 | 
					 | 
				
			||||||
						fallback: () => <NSpin size="small" />
 | 
											fallback: () => <NSpin size="small" />
 | 
				
			||||||
					}}
 | 
										}}
 | 
				
			||||||
				</Suspense>
 | 
									</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