mirror of
https://github.com/lights0123/n-link.git
synced 2024-12-23 02:35:27 +00:00
122 lines
3.1 KiB
Vue
122 lines
3.1 KiB
Vue
<template>
|
|
<div class="h-full">
|
|
<div class="border-b py-2 px-2 header flex">
|
|
<ol class="flex">
|
|
<li v-for="(part, i) in parts" :key="i" class="" :class="{active: i === parts.length - 1}">
|
|
<span class="inline-block cursor-pointer bg-gray-200 px-4 py-1 rounded-full"
|
|
@click="goToIndex(i)">{{ part || 'Home' }}</span>
|
|
<img v-if="i < parts.length - 1" class="inline img-fix" src="~feather-icons/dist/icons/chevron-right.svg"/>
|
|
</li>
|
|
</ol>
|
|
<div class="flex-grow"/>
|
|
<device-queue :device="$devices.devices[dev]"/>
|
|
</div>
|
|
<div class="h-full flex w-full body">
|
|
<div class="overflow-auto h-full py-4 flex-grow">
|
|
<file-view v-if="!loading && files" :files="files" :show-hidden="showHidden" @nav="path = $event"
|
|
@select="selected = $event"/>
|
|
<div v-else-if="loading" class="flex items-center justify-center h-full">
|
|
<div class="lds-dual-ring"/>
|
|
</div>
|
|
</div>
|
|
<div class="overflow-auto h-full px-4 pt-4 w-48 flex-shrink-0 border-l">
|
|
<file-data :files="selected" :show-hidden="showHidden" :dev="dev" :path="path" :native-upload="nativeUpload"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import {Component, Prop, Vue, Watch} from 'vue-property-decorator';
|
|
import FileView from './FileView.vue';
|
|
import type {FileInfo} from "./devices";
|
|
import FileData from "./FileData.vue";
|
|
import DeviceQueue from "./DeviceQueue.vue";
|
|
|
|
@Component({
|
|
asyncComputed: {
|
|
files: {
|
|
async get(this: FileBrowser) {
|
|
try {
|
|
this.updateIndex;
|
|
return (await this.$devices.listDir(this.dev, this.path)).map(file => ({
|
|
...file,
|
|
path: `${this.path}/${file.path}`
|
|
}));
|
|
} catch (e) {
|
|
console.error(e);
|
|
throw e;
|
|
}
|
|
},
|
|
default: null,
|
|
}
|
|
},
|
|
components: {DeviceQueue, FileData, FileView}
|
|
})
|
|
export default class FileBrowser extends Vue {
|
|
@Prop({type: String, required: true}) private dev!: string;
|
|
@Prop({type: Boolean, default: false}) private showHidden!: boolean;
|
|
@Prop({type: Boolean, default: false}) private nativeUpload!: boolean;
|
|
path = '';
|
|
updateIndex = 0;
|
|
selected: FileInfo[] = [];
|
|
files!: FileInfo[] | null;
|
|
|
|
@Watch('path')
|
|
onPathChange() {
|
|
this.selected = [];
|
|
}
|
|
|
|
get parts() {
|
|
return this.path.split('/');
|
|
}
|
|
|
|
get loading() {
|
|
return this.$asyncComputed.files.updating;
|
|
}
|
|
|
|
goToIndex(i: number) {
|
|
this.path = this.parts.slice(0, i + 1).join('/');
|
|
this.updateIndex++;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.header {
|
|
height: 50px;
|
|
}
|
|
|
|
.body {
|
|
padding-bottom: 50px;
|
|
}
|
|
|
|
.active span {
|
|
@apply bg-blue-500 text-white;
|
|
}
|
|
|
|
.img-fix {
|
|
margin-top: -1px;
|
|
}
|
|
|
|
.lds-dual-ring {
|
|
display: inline-block;
|
|
width: 80px;
|
|
height: 80px;
|
|
}
|
|
|
|
.lds-dual-ring:after {
|
|
$color: theme('colors.gray.400');
|
|
content: " ";
|
|
display: block;
|
|
width: 64px;
|
|
height: 64px;
|
|
margin: 8px;
|
|
border-radius: 50%;
|
|
border: 6px solid $color;
|
|
border-color: $color transparent $color transparent;
|
|
animation: lds-dual-ring 1.2s linear infinite;
|
|
}
|
|
|
|
</style>
|