132 lines
3.2 KiB
TypeScript
132 lines
3.2 KiB
TypeScript
import generateId from "@/hooks/generateId";
|
|
import type { stats, file, directory } from "@/types/type.ts";
|
|
|
|
export class VirtualFile {
|
|
constructor(info: file, parent: VirtualDirectory) {
|
|
this.name = info.name;
|
|
this.size = info.size;
|
|
this.stats = info.stats;
|
|
this.parent = parent;
|
|
this.type = "file";
|
|
this.uid = generateId();
|
|
}
|
|
name: string;
|
|
type: "file";
|
|
size: number;
|
|
stats: stats;
|
|
parent: VirtualDirectory;
|
|
uid: number;
|
|
get path() {
|
|
return `${this.parent.path}${this.name}`;
|
|
}
|
|
}
|
|
|
|
class VirtualDirectory {
|
|
constructor(info: directory, parent?: VirtualDirectory) {
|
|
this.name = info.name;
|
|
this.type = "directory";
|
|
this.stats = info.stats;
|
|
this.parent = parent ?? undefined;
|
|
this.uid = generateId();
|
|
}
|
|
// 文件夹名
|
|
name: string;
|
|
// 子文件
|
|
files?: VirtualFile[];
|
|
// 子目录
|
|
directorys?: VirtualDirectory[];
|
|
// 没啥意义,标注一下就是了
|
|
type: "directory";
|
|
// 文件夹创建时间等杂项属性
|
|
stats: stats;
|
|
// 父文件夹
|
|
parent?: VirtualDirectory;
|
|
|
|
uid: number;
|
|
|
|
/**
|
|
* 获取相对于根目录的路径的层数
|
|
* 用于目录下文件定位
|
|
* @returns {string}
|
|
*/
|
|
get layer(): number {
|
|
return this.parent ? this.parent.layer + 1 : 0;
|
|
}
|
|
/**
|
|
* 相对于根目录的路径, 如: "/", "/123/321/"
|
|
* 用于目录下文件定位
|
|
* @returns {string}
|
|
*/
|
|
get path(): string {
|
|
if (!this.parent) {
|
|
return "/";
|
|
}
|
|
return `${this.parent.path}${this.name}/`;
|
|
}
|
|
|
|
/**
|
|
* 获取从根目录开始的按顺序的文件夹
|
|
* @returns {VirtualDirectory[]}
|
|
*/
|
|
get directoryArray(): VirtualDirectory[] {
|
|
if (!this.parent) {
|
|
return [this];
|
|
}
|
|
return [...this.parent.directoryArray, this];
|
|
}
|
|
|
|
/**
|
|
* 获取 layer 级父文件夹, 如getParent(1)就返回父级
|
|
* @param {number} layer 需要跳转的层数
|
|
* @returns {VirtualDirectory}
|
|
*/
|
|
getParent(layer: number): VirtualDirectory {
|
|
if (layer <= 0 || !this.parent) {
|
|
return this;
|
|
}
|
|
return this.parent.getParent(layer - 1);
|
|
}
|
|
|
|
updateContent(content: (file | directory)[]) {
|
|
this.files = this.files ?? [];
|
|
this.directorys = this.directorys ?? [];
|
|
const fileNames: string[] = this.files.map(v => v.name);
|
|
const dirNames: string[] = this.directorys.map(v => v.name);
|
|
const itemNames: string[] = content.map(v => v.name);
|
|
// 删去远程端已不存在的文件与文件夹
|
|
const _delete = (target: (VirtualFile | VirtualDirectory)[]) => {
|
|
let index = 0;
|
|
while (index < target.length) {
|
|
if (!itemNames.includes(target[index].name)) {
|
|
target.splice(index, 1);
|
|
} else {
|
|
index += 1;
|
|
}
|
|
}
|
|
};
|
|
_delete(this.files);
|
|
_delete(this.directorys);
|
|
// 加入新的文件与文件夹
|
|
for (let item of content) {
|
|
if (item.type === "file") {
|
|
if (!fileNames.includes(item.name)) {
|
|
this.files.push(new VirtualFile(item, this));
|
|
}
|
|
} else if (item.type === "directory") {
|
|
if (!dirNames.includes(item.name)) {
|
|
this.directorys.push(new VirtualDirectory(item, this));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hasChild(item: VirtualDirectory | VirtualFile): boolean {
|
|
if (item.type === "directory") {
|
|
return this.directorys?.includes(item) ?? false;
|
|
} else {
|
|
return this.files?.includes(item) ?? false;
|
|
}
|
|
}
|
|
}
|
|
export default VirtualDirectory;
|