mirror of
https://github.com/lights0123/n-link.git
synced 2026-08-08 02:33:28 +00:00
feat(core): port CalcInfo and FileView to Vue 3 script setup
This commit is contained in:
parent
7869a747bc
commit
3ee9925f91
|
|
@ -31,7 +31,7 @@
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button class="mt-4 button gray-button"
|
<button class="mt-4 button gray-button"
|
||||||
@click="nativeUpload ? $refs.upload.click() : $devices.uploadOs(dev, info.os_extension.split('.').pop())">
|
@click="nativeUpload ? upload?.click() : $devices.uploadOs(dev, info.os_extension.split('.').pop())">
|
||||||
Upload OS
|
Upload OS
|
||||||
</button>
|
</button>
|
||||||
<input v-if="nativeUpload" ref="upload" type="file" class="hidden" :accept="info.os_extension"
|
<input v-if="nativeUpload" ref="upload" type="file" class="hidden" :accept="info.os_extension"
|
||||||
|
|
@ -39,40 +39,45 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import {Component, Prop, Vue} from 'vue-property-decorator';
|
import {inject, ref} from 'vue';
|
||||||
import type {Info, Version} from './devices';
|
import {DEVICES_KEY, type GenericDevices, type Info, type Version} from './devices';
|
||||||
import fileSize from "filesize";
|
import {filesize} from 'filesize';
|
||||||
|
|
||||||
@Component
|
const props = withDefaults(defineProps<{
|
||||||
export default class FileView extends Vue {
|
info: Info;
|
||||||
@Prop({type: Object, required: true}) private info!: Info;
|
dev: string;
|
||||||
@Prop({type: String, required: true}) private dev!: string;
|
nativeUpload?: boolean;
|
||||||
@Prop({type: Boolean, default: false}) private nativeUpload!: boolean;
|
}>(), {
|
||||||
refreshing = false;
|
nativeUpload: false,
|
||||||
|
});
|
||||||
|
|
||||||
formatSize(size: number) {
|
const devices = inject(DEVICES_KEY) as GenericDevices;
|
||||||
return fileSize(size, {round: 1});
|
|
||||||
|
const refreshing = ref(false);
|
||||||
|
const upload = ref<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
function formatSize(size: number) {
|
||||||
|
return filesize(size, {round: 1});
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatVersion(version: Version) {
|
||||||
|
return `${version.major}.${version.minor}.${version.patch}.${version.build}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
refreshing.value = true;
|
||||||
|
try {
|
||||||
|
await devices.update(props.dev);
|
||||||
|
} catch (e) {
|
||||||
|
/* */
|
||||||
}
|
}
|
||||||
|
refreshing.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
formatVersion(version: Version) {
|
function uploadNative(e: Event & { target: HTMLInputElement }) {
|
||||||
return `${version.major}.${version.minor}.${version.patch}.${version.build}`;
|
const file = e.target.files?.[0];
|
||||||
}
|
if (file) devices.uploadOsFile(props.dev, file);
|
||||||
|
|
||||||
async refresh() {
|
|
||||||
this.refreshing = true;
|
|
||||||
try {
|
|
||||||
await this.$devices.update(this.dev);
|
|
||||||
} catch (e) {
|
|
||||||
/* */
|
|
||||||
}
|
|
||||||
this.refreshing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uploadNative(e: Event & { target: HTMLInputElement }) {
|
|
||||||
const file = e.target.files?.[0];
|
|
||||||
if (file) this.$devices.uploadOsFile(this.dev, file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,55 +10,59 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import {Component, Prop, Vue, Watch} from 'vue-property-decorator';
|
import {computed, ref, watch} from 'vue';
|
||||||
import type {FileInfo} from './devices';
|
import type {FileInfo} from './devices';
|
||||||
import FileIcon from "./FileIcon.vue";
|
import FileIcon from './FileIcon.vue';
|
||||||
|
|
||||||
@Component({
|
const props = withDefaults(defineProps<{
|
||||||
components: {FileIcon}
|
files: FileInfo[];
|
||||||
})
|
showHidden?: boolean;
|
||||||
export default class FileView extends Vue {
|
}>(), {
|
||||||
@Prop({type: Array, default: () => ([])}) private files!: FileInfo[];
|
files: () => [],
|
||||||
@Prop({type: Boolean, default: false}) private showHidden!: boolean;
|
showHidden: false,
|
||||||
selected: number[] = [];
|
});
|
||||||
|
|
||||||
@Watch('selected', {deep: true, immediate: true})
|
const emit = defineEmits<{
|
||||||
onSelect(selected: number[]) {
|
nav: [path: string];
|
||||||
this.$emit('select', selected.map(file => this.filteredFiles[file]));
|
select: [files: FileInfo[]];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const selected = ref<number[]>([]);
|
||||||
|
|
||||||
|
const filteredFiles = computed(() => {
|
||||||
|
if (props.showHidden) return props.files;
|
||||||
|
return props.files.filter(file => file.isDir || file.path.endsWith('.tns'));
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(selected, (sel) => {
|
||||||
|
emit('select', sel.map(file => filteredFiles.value[file]));
|
||||||
|
}, {deep: true, immediate: true});
|
||||||
|
|
||||||
|
watch(() => props.files, () => {
|
||||||
|
selected.value = [];
|
||||||
|
});
|
||||||
|
|
||||||
|
function formatPath({path, isDir}: FileInfo) {
|
||||||
|
const name = path.split('/').pop() as string;
|
||||||
|
if (props.showHidden || isDir) return name;
|
||||||
|
return name.substring(0, name.length - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
function xorSelection(i: number) {
|
||||||
|
if (selected.value.includes(i)) selected.value = selected.value.filter(num => num !== i);
|
||||||
|
else selected.value.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shiftSelection(item: number) {
|
||||||
|
const lastSelected = selected.value[selected.value.length - 1];
|
||||||
|
if (lastSelected === undefined) {
|
||||||
|
selected.value.push(item);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const [lower, upper] = item > lastSelected ? [lastSelected, item] : [item, lastSelected];
|
||||||
@Watch('files')
|
for (let i = lower; i <= upper; i++) {
|
||||||
onFileChange() {
|
if (!selected.value.includes(i)) selected.value.push(i);
|
||||||
this.selected = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
get filteredFiles() {
|
|
||||||
if (this.showHidden) return this.files;
|
|
||||||
return this.files.filter(file => file.isDir || file.path.endsWith('.tns'));
|
|
||||||
}
|
|
||||||
|
|
||||||
formatPath({path, isDir}: FileInfo) {
|
|
||||||
const name = path.split('/').pop() as string;
|
|
||||||
if (this.showHidden || isDir) return name;
|
|
||||||
return name.substring(0, name.length - 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
xorSelection(i: number) {
|
|
||||||
if (this.selected.includes(i)) this.selected = this.selected.filter(num => num !== i);
|
|
||||||
else this.selected.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
shiftSelection(item: number) {
|
|
||||||
const lastSelected = this.selected[this.selected.length-1];
|
|
||||||
if(lastSelected === undefined) {
|
|
||||||
this.selected.push(item);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const [lower, upper] = item > lastSelected ? [lastSelected, item] : [item, lastSelected];
|
|
||||||
for(let i = lower; i <= upper; i++) {
|
|
||||||
if (!this.selected.includes(i))this.selected.push(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue