You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
2.9 KiB
128 lines
2.9 KiB
2 months ago
|
import 'package:flutter/foundation.dart';
|
||
|
import 'package:flutter/material.dart';
|
||
|
|
||
|
class FileNode {
|
||
|
final String name;
|
||
|
final String path;
|
||
|
final bool isDirectory;
|
||
|
final bool isRoot;
|
||
|
final int depth;
|
||
|
List<FileNode> children;
|
||
|
bool isExpanded;
|
||
|
|
||
|
FileNode({
|
||
|
required this.name,
|
||
|
required this.path,
|
||
|
required this.isDirectory,
|
||
|
this.isRoot = false,
|
||
|
this.depth = 0,
|
||
|
this.isExpanded = false,
|
||
|
List<FileNode>? children,
|
||
|
}) : children = children ?? [];
|
||
|
|
||
|
// 获取文件图标数据
|
||
|
IconData get iconData {
|
||
|
if (isDirectory) {
|
||
|
return Icons.folder;
|
||
|
}
|
||
|
|
||
|
final ext = name.split('.').last.toLowerCase();
|
||
|
|
||
|
// 常见文件类型图标映射
|
||
|
switch (ext) {
|
||
|
case 'pdf':
|
||
|
return Icons.picture_as_pdf;
|
||
|
case 'doc':
|
||
|
case 'docx':
|
||
|
return Icons.article;
|
||
|
case 'xls':
|
||
|
case 'xlsx':
|
||
|
return Icons.table_chart;
|
||
|
case 'ppt':
|
||
|
case 'pptx':
|
||
|
return Icons.slideshow;
|
||
|
case 'txt':
|
||
|
return Icons.text_snippet;
|
||
|
case 'dart':
|
||
|
return Icons.code;
|
||
|
case 'js':
|
||
|
return Icons.javascript;
|
||
|
case 'java':
|
||
|
return Icons.coffee;
|
||
|
case 'py':
|
||
|
return Icons.data_object;
|
||
|
case 'html':
|
||
|
return Icons.html;
|
||
|
case 'css':
|
||
|
return Icons.css;
|
||
|
case 'json':
|
||
|
return Icons.data_array;
|
||
|
case 'png':
|
||
|
case 'jpg':
|
||
|
case 'jpeg':
|
||
|
case 'gif':
|
||
|
return Icons.image;
|
||
|
case 'mp3':
|
||
|
case 'wav':
|
||
|
return Icons.audiotrack;
|
||
|
case 'mp4':
|
||
|
case 'avi':
|
||
|
case 'mov':
|
||
|
return Icons.videocam;
|
||
|
case 'zip':
|
||
|
case 'rar':
|
||
|
case '7z':
|
||
|
return Icons.archive;
|
||
|
default:
|
||
|
return Icons.insert_drive_file;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 获取构建好的图标组件
|
||
|
Widget get icon {
|
||
|
return Icon(iconData, color: isDirectory ? Colors.amber[700] : Colors.blue);
|
||
|
}
|
||
|
|
||
|
FileNode copyWith({
|
||
|
String? name,
|
||
|
String? path,
|
||
|
bool? isDirectory,
|
||
|
bool? isRoot,
|
||
|
int? depth, // 添加depth参数
|
||
|
List<FileNode>? children,
|
||
|
bool? isExpanded,
|
||
|
}) {
|
||
|
return FileNode(
|
||
|
name: name ?? this.name,
|
||
|
path: path ?? this.path,
|
||
|
isDirectory: isDirectory ?? this.isDirectory,
|
||
|
isRoot: isRoot ?? this.isRoot,
|
||
|
depth: depth ?? this.depth, // 保留原有depth或使用新值
|
||
|
children: children ?? this.children,
|
||
|
isExpanded: isExpanded ?? this.isExpanded,
|
||
|
);
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
bool operator ==(Object other) {
|
||
|
if (identical(this, other)) return true;
|
||
|
return other is FileNode &&
|
||
|
other.name == name &&
|
||
|
other.path == path &&
|
||
|
other.isDirectory == isDirectory &&
|
||
|
other.isRoot == isRoot &&
|
||
|
listEquals(other.children, children) &&
|
||
|
other.isExpanded == isExpanded;
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
int get hashCode {
|
||
|
return name.hashCode ^
|
||
|
path.hashCode ^
|
||
|
isDirectory.hashCode ^
|
||
|
isRoot.hashCode ^
|
||
|
children.hashCode ^
|
||
|
isExpanded.hashCode;
|
||
|
}
|
||
|
}
|