mirror of
https://github.com/lights0123/n-link.git
synced 2026-08-08 10:43:29 +00:00
feat(core): port FileIcon to Vue 3, replace require() with import.meta.glob
30 webpack require() calls replaced by a single eager import.meta.glob. The extension-to-icon mapping is preserved exactly, restructured from a switch chain into lookup tables. Fixes alt="name" rendering the literal string 'name'.
This commit is contained in:
parent
49e9e3879e
commit
7869a747bc
|
|
@ -1,161 +1,97 @@
|
||||||
<template>
|
<template>
|
||||||
<img :width="width" :src="icon" alt="name"/>
|
<img :width="width" :src="icon" alt=""/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import {Component, Prop, Vue} from 'vue-property-decorator';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
@Component
|
const props = withDefaults(defineProps<{
|
||||||
export default class FileView extends Vue {
|
path: string;
|
||||||
@Prop({type: String, required: true}) private path!: string;
|
dir?: boolean;
|
||||||
@Prop({type: Boolean, default: false}) private dir!: string;
|
width?: number;
|
||||||
@Prop({type: Number, default: 64}) private width!: number;
|
}>(), {
|
||||||
|
dir: false,
|
||||||
|
width: 64,
|
||||||
|
});
|
||||||
|
|
||||||
get name() {
|
// Vite replacement for webpack's require(). Eagerly resolves every SVG in
|
||||||
return this.path.split('/').pop() as string;
|
// assets/ to its emitted URL at build time, keyed by module path.
|
||||||
}
|
const assets = import.meta.glob<string>('../assets/**/*.svg', {
|
||||||
|
eager: true,
|
||||||
|
query: '?url',
|
||||||
|
import: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
get ext() {
|
function asset(name: string): string {
|
||||||
const parts = this.name.split('.');
|
const key = `../assets/${name}`;
|
||||||
if (parts[parts.length - 1] === 'tns') parts.pop();
|
const found = assets[key];
|
||||||
if (parts.length < 2) return '';
|
if (!found) throw new Error(`missing icon asset: ${key}`);
|
||||||
return parts.pop() as string;
|
return found;
|
||||||
}
|
|
||||||
|
|
||||||
get icon() {
|
|
||||||
if (this.dir) {
|
|
||||||
switch (this.name.trim().toLowerCase()) {
|
|
||||||
case 'games':
|
|
||||||
return require('../assets/folders/games.svg');
|
|
||||||
case 'images':
|
|
||||||
case 'photos':
|
|
||||||
return require('../assets/folders/images.svg');
|
|
||||||
case 'music':
|
|
||||||
case 'sound':
|
|
||||||
case 'sounds':
|
|
||||||
return require('../assets/folders/music.svg');
|
|
||||||
case 'script':
|
|
||||||
case 'scripts':
|
|
||||||
case 'program':
|
|
||||||
case 'programs':
|
|
||||||
return require('../assets/folders/scripts.svg');
|
|
||||||
case 'template':
|
|
||||||
case 'templates':
|
|
||||||
return require('../assets/folders/templates.svg');
|
|
||||||
case 'video':
|
|
||||||
case 'videos':
|
|
||||||
return require('../assets/folders/video.svg');
|
|
||||||
default:
|
|
||||||
return require('../assets/folders/folder.svg');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.name === 'ndless_resources.tns') return require('../assets/files/resources.svg');
|
|
||||||
if (this.name.startsWith('ndless_installer')) return require('../assets/files/installer.svg');
|
|
||||||
switch (this.ext.toLowerCase()) {
|
|
||||||
case 'bin':
|
|
||||||
return require('../assets/files/binary.svg');
|
|
||||||
case 'ical':
|
|
||||||
case 'ics':
|
|
||||||
case 'ifb':
|
|
||||||
case 'icalendar':
|
|
||||||
return require('../assets/files/calendar.svg');
|
|
||||||
case 'cfg':
|
|
||||||
return require('../assets/files/cfg.svg');
|
|
||||||
case 'vcf':
|
|
||||||
return require('../assets/files/contact.svg');
|
|
||||||
case 'csv':
|
|
||||||
case 'log':
|
|
||||||
case 'logs':
|
|
||||||
return require('../assets/files/csv.svg');
|
|
||||||
case 'sql':
|
|
||||||
case 'db':
|
|
||||||
case 'sqlite':
|
|
||||||
return require('../assets/files/db.svg');
|
|
||||||
case 'epub':
|
|
||||||
return require('../assets/files/epub.svg');
|
|
||||||
case 'eot':
|
|
||||||
case 'otf':
|
|
||||||
case 'ttf':
|
|
||||||
case 'woff':
|
|
||||||
case 'woff2':
|
|
||||||
return require('../assets/files/font.svg');
|
|
||||||
case 'png':
|
|
||||||
case 'bmp':
|
|
||||||
case 'jpg':
|
|
||||||
case 'jpeg':
|
|
||||||
case 'jpe':
|
|
||||||
case 'jif':
|
|
||||||
case 'jfif':
|
|
||||||
case 'jfi':
|
|
||||||
case 'jp2':
|
|
||||||
case 'j2k':
|
|
||||||
case 'jpf':
|
|
||||||
case 'jpx':
|
|
||||||
case 'jpm':
|
|
||||||
case 'mj2':
|
|
||||||
case 'gif':
|
|
||||||
case 'tiff':
|
|
||||||
case 'tif':
|
|
||||||
case 'ppm':
|
|
||||||
case 'pgm':
|
|
||||||
case 'pbm':
|
|
||||||
case 'pnm':
|
|
||||||
case 'webp':
|
|
||||||
case 'heif':
|
|
||||||
case 'heifs':
|
|
||||||
case 'heic':
|
|
||||||
case 'heics':
|
|
||||||
case 'avci':
|
|
||||||
case 'avcs':
|
|
||||||
case 'avif':
|
|
||||||
case 'avifs':
|
|
||||||
case 'ico':
|
|
||||||
case 'icon':
|
|
||||||
case 'icns':
|
|
||||||
case 'pcx':
|
|
||||||
case 'pgf':
|
|
||||||
case 'tga':
|
|
||||||
case 'psd':
|
|
||||||
case 'xcf':
|
|
||||||
return require('../assets/files/image.svg');
|
|
||||||
case 'js':
|
|
||||||
case 'mjs':
|
|
||||||
return require('../assets/files/js.svg');
|
|
||||||
case 'json':
|
|
||||||
case 'json5':
|
|
||||||
return require('../assets/files/json.svg');
|
|
||||||
case 'lua':
|
|
||||||
return require('../assets/files/lua.svg');
|
|
||||||
case 'pdf':
|
|
||||||
return require('../assets/files/pdf.svg');
|
|
||||||
case 'py':
|
|
||||||
return require('../assets/files/python.svg');
|
|
||||||
case 'rom':
|
|
||||||
case '89u':
|
|
||||||
case 'smc':
|
|
||||||
case 'sfc':
|
|
||||||
case 'srm':
|
|
||||||
case 'img':
|
|
||||||
return require('../assets/files/rom.svg');
|
|
||||||
case 'svg':
|
|
||||||
case 'svgz':
|
|
||||||
return require('../assets/files/svg.svg');
|
|
||||||
case 'txt':
|
|
||||||
return require('../assets/files/txt.svg');
|
|
||||||
case 'mp4':
|
|
||||||
return require('../assets/files/video.svg');
|
|
||||||
case 'xml':
|
|
||||||
return require('../assets/files/xml.svg');
|
|
||||||
case 'zip':
|
|
||||||
case 'tar':
|
|
||||||
case 'gz':
|
|
||||||
return require('../assets/files/zip.svg');
|
|
||||||
default:
|
|
||||||
return require('../assets/files/unknown.svg');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
const FOLDER_ICONS: Record<string, string> = {
|
||||||
</style>
|
games: 'games',
|
||||||
|
images: 'images',
|
||||||
|
photos: 'images',
|
||||||
|
music: 'music',
|
||||||
|
sound: 'music',
|
||||||
|
sounds: 'music',
|
||||||
|
script: 'scripts',
|
||||||
|
scripts: 'scripts',
|
||||||
|
program: 'scripts',
|
||||||
|
programs: 'scripts',
|
||||||
|
template: 'templates',
|
||||||
|
templates: 'templates',
|
||||||
|
video: 'video',
|
||||||
|
videos: 'video',
|
||||||
|
};
|
||||||
|
|
||||||
|
const EXT_ICONS: Record<string, string> = {
|
||||||
|
bin: 'binary',
|
||||||
|
ical: 'calendar', ics: 'calendar', ifb: 'calendar', icalendar: 'calendar',
|
||||||
|
cfg: 'cfg',
|
||||||
|
vcf: 'contact',
|
||||||
|
csv: 'csv', log: 'csv', logs: 'csv',
|
||||||
|
sql: 'db', db: 'db', sqlite: 'db',
|
||||||
|
epub: 'epub',
|
||||||
|
eot: 'font', otf: 'font', ttf: 'font', woff: 'font', woff2: 'font',
|
||||||
|
png: 'image', bmp: 'image', jpg: 'image', jpeg: 'image', jpe: 'image',
|
||||||
|
jif: 'image', jfif: 'image', jfi: 'image', jp2: 'image', j2k: 'image',
|
||||||
|
jpf: 'image', jpx: 'image', jpm: 'image', mj2: 'image', gif: 'image',
|
||||||
|
tiff: 'image', tif: 'image', ppm: 'image', pgm: 'image', pbm: 'image',
|
||||||
|
pnm: 'image', webp: 'image', heif: 'image', heifs: 'image', heic: 'image',
|
||||||
|
heics: 'image', avci: 'image', avcs: 'image', avif: 'image', avifs: 'image',
|
||||||
|
ico: 'image', icon: 'image', icns: 'image', pcx: 'image', pgf: 'image',
|
||||||
|
tga: 'image', psd: 'image', xcf: 'image',
|
||||||
|
js: 'js', mjs: 'js',
|
||||||
|
json: 'json', json5: 'json',
|
||||||
|
lua: 'lua',
|
||||||
|
pdf: 'pdf',
|
||||||
|
py: 'python',
|
||||||
|
rom: 'rom', '89u': 'rom', smc: 'rom', sfc: 'rom', srm: 'rom', img: 'rom',
|
||||||
|
svg: 'svg', svgz: 'svg',
|
||||||
|
txt: 'txt',
|
||||||
|
mp4: 'video',
|
||||||
|
xml: 'xml',
|
||||||
|
zip: 'zip', tar: 'zip', gz: 'zip',
|
||||||
|
};
|
||||||
|
|
||||||
|
const name = computed(() => props.path.split('/').pop() as string);
|
||||||
|
|
||||||
|
const ext = computed(() => {
|
||||||
|
const parts = name.value.split('.');
|
||||||
|
if (parts[parts.length - 1] === 'tns') parts.pop();
|
||||||
|
if (parts.length < 2) return '';
|
||||||
|
return parts.pop() as string;
|
||||||
|
});
|
||||||
|
|
||||||
|
const icon = computed(() => {
|
||||||
|
if (props.dir) {
|
||||||
|
const key = FOLDER_ICONS[name.value.trim().toLowerCase()] ?? 'folder';
|
||||||
|
return asset(`folders/${key}.svg`);
|
||||||
|
}
|
||||||
|
if (name.value === 'ndless_resources.tns') return asset('files/resources.svg');
|
||||||
|
if (name.value.startsWith('ndless_installer')) return asset('files/installer.svg');
|
||||||
|
return asset(`files/${EXT_ICONS[ext.value.toLowerCase()] ?? 'unknown'}.svg`);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue