diff --git a/src/components/common/FormatTime.vue b/src/components/common/FormatTime.vue new file mode 100644 index 0000000..08d933e --- /dev/null +++ b/src/components/common/FormatTime.vue @@ -0,0 +1,32 @@ +<template> + <span> + {{ formatted }} + </span> +</template> + +<script lang="ts" setup> +import { computed } from 'vue'; + +const props = defineProps<{ + datetime: number; +}>(); + +const date = new Date(props.datetime); +const formatter = Intl.DateTimeFormat('zh-CN', { + timeZone: 'Asia/Shanghai', + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: "numeric", +}); + +const formatted = computed(() => { + return formatter.format(date); +}); +console.log('I had loaded'); +</script> + +<style lang="scss" module> +</style> diff --git a/src/components/common/PartitionTable.vue b/src/components/common/PartitionTable.vue index 15012ca..c036a46 100644 --- a/src/components/common/PartitionTable.vue +++ b/src/components/common/PartitionTable.vue @@ -39,6 +39,11 @@ const columns: DataTableColumns<IPartition> = [ key: 'addr', width: '10em', }, + { + title: '文件修改时间', + key: 'modified-at', + width: '13em', + }, { title: '大小', key: 'size', diff --git a/src/components/sections/PartitionView.vue b/src/components/sections/PartitionView.vue index 645674f..bd7f726 100644 --- a/src/components/sections/PartitionView.vue +++ b/src/components/sections/PartitionView.vue @@ -101,6 +101,11 @@ <field-addr v-model:value="state![index].addr" :placeholder="toHex(image.partitions[index].addr)" :disabled="props.busy" @blur="() => handleAddrInputBlur(index)" /> </template> + <template #column-modified-at="{ data }"> + <field-base> + <format-time :datetime="data.file.modifiedAt" /> + </field-base> + </template> <template #column-size="{ data }"> <field-base> <file-size :size="data.file.size" /> @@ -206,6 +211,7 @@ import { FlashStatus, type IFlashProgress } from '@/composables/progress'; import FileDropper from '@/components/common/FileDropper.vue'; import FileSize from '@/components/common/FileSize.vue'; +import FormatTime from '@/components/common/FormatTime.vue'; import SelectableText from '@/components/common/SelectableText.vue'; import PartitionTable from '@/components/common/PartitionTable.vue'; diff --git a/src/utils/file.ts b/src/utils/file.ts index 183d40c..78e6ca6 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -15,6 +15,11 @@ export interface IFileRef { */ containerPath?: string; + /** + * Timestamp of the last modification of the file. + */ + modifiedAt?: number; + /** * Display name of the file. */ @@ -59,7 +64,8 @@ class BaseFile implements IFileRef { constructor( readonly path: string, readonly name: string, - readonly size: number) { + readonly size: number, + readonly modifiedAt: number) { } async content(): Promise<Uint8Array> { @@ -74,12 +80,12 @@ class BaseFile implements IFileRef { export class LocalFile extends BaseFile { static async from(path: string): Promise<LocalFile> { const name = await basename(path); - const { size } = await stat(path); - return new LocalFile(path, name, size); + const { size, mtime } = await stat(path); + return new LocalFile(path, name, size, mtime!.getTime()); } - private constructor(path: string, name: string, size: number) { - super(path, name, size); + private constructor(path: string, name: string, size: number, mtime: number) { + super(path, name, size, mtime); } } @@ -91,17 +97,18 @@ export class TmpFile extends BaseFile { const name = await basename(pseudoPath); await writeFile(path, content); + const { mtime } = await stat(path); - return new TmpFile(path, name, content.length, containerPath); + return new TmpFile(path, name, content.length, mtime!.getTime(), containerPath); } static clone(base: TmpFile): TmpFile { - return new TmpFile(base.path, base.name, base.size, base.containerPath); + return new TmpFile(base.path, base.name, base.size, base.modifiedAt, base.containerPath); } - private constructor(path: string, name: string, size: number, + private constructor(path: string, name: string, size: number, readonly modifiedAt: number, readonly containerPath?: string) { - super(path, name, size); + super(path, name, size, modifiedAt); } async free(): Promise<void> {