Fix some known issues and add some new functions
Android APK Release / Build Android APK (push) Failing after 52m53s

This commit is contained in:
2026-05-25 20:03:59 +08:00
parent 74abb4a1c5
commit 39d8361080
8 changed files with 587 additions and 221 deletions
+116 -17
View File
@@ -8,6 +8,64 @@ class FileUtils {
final cleanPath = path.startsWith('/') ? path.substring(1) : path;
return 'cloudreve://my/$cleanPath';
}
static String toCloudreveUriWithQuery(
String path,
Map<String, Object?> queryParameters,
) {
final baseUri = toCloudreveUri(path);
final filteredQuery = <String, String>{};
for (final entry in queryParameters.entries) {
final value = entry.value;
if (value != null) {
filteredQuery[entry.key] = value.toString();
}
}
if (filteredQuery.isEmpty) return baseUri;
final query = Uri(queryParameters: filteredQuery).query;
final separator = baseUri.contains('?') ? '&' : '?';
return '$baseUri$separator$query';
}
static String toRelativePath(String path) {
const prefix = 'cloudreve://my';
if (!path.startsWith(prefix)) {
return path.isEmpty ? '/' : path;
}
var relative = path.substring(prefix.length);
final queryIndex = relative.indexOf('?');
if (queryIndex != -1) {
relative = relative.substring(0, queryIndex);
}
return relative.isEmpty ? '/' : relative;
}
static String decodePathForDisplay(String path) {
final relativePath = toRelativePath(path);
return relativePath.split('/').map(decodePathSegment).join('/');
}
static String decodePathSegment(String value) {
var decoded = value;
for (var i = 0; i < 5; i++) {
try {
final next = Uri.decodeComponent(decoded);
if (next == decoded) break;
decoded = next;
} on FormatException {
break;
}
}
return decoded;
}
/// 获取文件扩展名
static String getFileExtension(String fileName) {
final dotIndex = fileName.lastIndexOf('.');
@@ -18,24 +76,27 @@ class FileUtils {
/// 判断是否为图片文件
static bool isImageFile(String fileName) {
const imageExtensions = [
'jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'heic'
'jpg',
'jpeg',
'png',
'gif',
'webp',
'bmp',
'svg',
'heic',
];
return imageExtensions.contains(getFileExtension(fileName));
}
/// 判断是否为视频文件
static bool isVideoFile(String fileName) {
const videoExtensions = [
'mp4', 'webm', 'mkv', 'avi', 'mov', 'flv', 'wmv'
];
const videoExtensions = ['mp4', 'webm', 'mkv', 'avi', 'mov', 'flv', 'wmv'];
return videoExtensions.contains(getFileExtension(fileName));
}
/// 判断是否为音频文件
static bool isAudioFile(String fileName) {
const audioExtensions = [
'mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a'
];
const audioExtensions = ['mp3', 'wav', 'ogg', 'flac', 'aac', 'm4a'];
return audioExtensions.contains(getFileExtension(fileName));
}
@@ -47,7 +108,14 @@ class FileUtils {
/// 判断是否为文本文件
static bool isTextFile(String fileName) {
const textExtensions = [
'txt', 'md', 'json', 'xml', 'yaml', 'yml', 'ini', 'conf'
'txt',
'md',
'json',
'xml',
'yaml',
'yml',
'ini',
'conf',
];
return textExtensions.contains(getFileExtension(fileName));
}
@@ -55,33 +123,64 @@ class FileUtils {
/// 判断是否为代码文件
static bool isCodeFile(String fileName) {
const codeExtensions = [
'js', 'ts', 'tsx', 'jsx', 'dart', 'java', 'py', 'c', 'cpp',
'h', 'hpp', 'cs', 'php', 'rb', 'go', 'rs', 'swift', 'kt',
'html', 'css', 'scss', 'less', 'sql', 'sh', 'bat'
'js',
'ts',
'tsx',
'jsx',
'dart',
'java',
'py',
'c',
'cpp',
'h',
'hpp',
'cs',
'php',
'rb',
'go',
'rs',
'swift',
'kt',
'html',
'css',
'scss',
'less',
'sql',
'sh',
'bat',
];
return codeExtensions.contains(getFileExtension(fileName));
}
/// 判断是否为压缩文件
static bool isArchiveFile(String fileName) {
const archiveExtensions = [
'zip', 'rar', '7z', 'tar', 'gz', 'bz2'
];
const archiveExtensions = ['zip', 'rar', '7z', 'tar', 'gz', 'bz2'];
return archiveExtensions.contains(getFileExtension(fileName));
}
/// 判断是否为文档文件
static bool isDocumentFile(String fileName) {
const docExtensions = [
'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'odt', 'ods', 'odp'
'doc',
'docx',
'xls',
'xlsx',
'ppt',
'pptx',
'odt',
'ods',
'odp',
];
return docExtensions.contains(getFileExtension(fileName));
}
/// 判断是否可预览
static bool isPreviewable(String fileName) {
return isImageFile(fileName) || isVideoFile(fileName) ||
isPdfFile(fileName) || isTextFile(fileName) || isCodeFile(fileName);
return isImageFile(fileName) ||
isVideoFile(fileName) ||
isPdfFile(fileName) ||
isTextFile(fileName) ||
isCodeFile(fileName);
}
/// 获取MIME类型