二次开发源码提交

This commit is contained in:
2026-05-15 08:52:48 +08:00
parent 4131f7321a
commit eb35a1d067
191 changed files with 34566 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
/// 应用常量
class AppConstants {
// 存储键
static const String keyAccessToken = 'access_token';
static const String keyRefreshToken = 'refresh_token';
static const String keyAccessExpires = 'access_expires';
static const String keyRefreshExpires = 'refresh_expires';
static const String keyRememberMe = 'remember_me';
static const String keyThemeMode = 'theme_mode';
static const String keyLanguage = 'language';
// 文件类型
static const int fileTypeFile = 0;
static const int fileTypeFolder = 1;
// 默认图标
static const String defaultAvatar = 'assets/images/default_avatar.png';
// 时间格式
static const String dateFormat = 'yyyy-MM-dd';
static const String dateTimeFormat = 'yyyy-MM-dd HH:mm:ss';
static const String timeFormat = 'HH:mm:ss';
}
/// API响应码
class ApiCode {
static const int success = 0;
static const int continueCode = 203;
static const int credentialInvalid = 40020;
static const int incorrectPassword = 40069;
static const int lockConflict = 40073;
static const int staleVersion = 40076;
static const int credentialRequired = 401;
static const int permissionDenied = 403;
static const int notFound = 404;
static const int internalError = 500;
}
@@ -0,0 +1,127 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:lucide_icons/lucide_icons.dart';
class QuickAccessConfig {
final String id;
final String label;
final IconData icon;
final String path;
final Color color;
final bool isDefault;
const QuickAccessConfig({
required this.id,
required this.label,
required this.icon,
required this.path,
required this.color,
this.isDefault = false,
});
QuickAccessConfig copyWith({String? label, String? path, IconData? icon, Color? color}) =>
QuickAccessConfig(
id: id,
label: label ?? this.label,
icon: icon ?? this.icon,
path: path ?? this.path,
color: color ?? this.color,
isDefault: isDefault,
);
static const storageKey = 'quick_access_shortcuts_v2';
static const defaults = [
QuickAccessConfig(id: 'img', label: '图片', icon: LucideIcons.image, path: '/Images', color: Color(0xFFF0ABFC), isDefault: true),
QuickAccessConfig(id: 'vid', label: '视频', icon: LucideIcons.video, path: '/Videos', color: Color(0xFFFCD34D), isDefault: true),
QuickAccessConfig(id: 'doc', label: '文档', icon: LucideIcons.fileText, path: '/Documents', color: Color(0xFF93C5FD), isDefault: true),
QuickAccessConfig(id: 'mus', label: '音乐', icon: LucideIcons.music, path: '/Music', color: Color(0xFF86EFAC), isDefault: true),
];
static const iconPool = <IconData>[
LucideIcons.image,
LucideIcons.video,
LucideIcons.fileText,
LucideIcons.music,
LucideIcons.folder,
LucideIcons.download,
LucideIcons.archive,
LucideIcons.code,
LucideIcons.bookOpen,
LucideIcons.camera,
LucideIcons.film,
LucideIcons.headphones,
];
static const colorPool = <Color>[
Color(0xFFF0ABFC),
Color(0xFFFCD34D),
Color(0xFF93C5FD),
Color(0xFF86EFAC),
Color(0xFFFCA5A5),
Color(0xFFFDBA74),
Color(0xFFC4B5FD),
Color(0xFF67E8F9),
];
Map<String, dynamic> toJson() => {
'id': id,
'label': label,
'iconCode': icon.codePoint,
'path': path,
'color': color.toARGB32(),
'isDefault': isDefault,
};
factory QuickAccessConfig.fromJson(Map<String, dynamic> json) {
final iconCode = json['iconCode'] as int? ?? LucideIcons.folder.codePoint;
final matchedIcon = iconPool.cast<IconData?>().firstWhere(
(i) => i!.codePoint == iconCode,
orElse: () => LucideIcons.folder,
)!;
return QuickAccessConfig(
id: json['id'] as String? ?? DateTime.now().millisecondsSinceEpoch.toString(),
label: json['label'] as String,
icon: matchedIcon,
path: json['path'] as String,
color: Color(json['color'] as int? ?? 0xFF93C5FD),
isDefault: json['isDefault'] as bool? ?? false,
);
}
static List<QuickAccessConfig> parseSaved(String saved) {
try {
final list = jsonDecode(saved) as List<dynamic>;
return list.map((e) => QuickAccessConfig.fromJson(e as Map<String, dynamic>)).toList();
} catch (_) {
return List.from(defaults);
}
}
static String serialize(List<QuickAccessConfig> items) {
return jsonEncode(items.map((e) => e.toJson()).toList());
}
/// 迁移旧格式(分号分隔的路径列表)
static List<QuickAccessConfig> migrateV1(String saved) {
final parts = saved.split(';');
final items = <QuickAccessConfig>[];
for (int i = 0; i < defaults.length; i++) {
if (i < parts.length && parts[i].isNotEmpty) {
items.add(defaults[i].copyWith(path: parts[i]));
} else {
items.add(defaults[i]);
}
}
return items;
}
}
extension ColorDarken on Color {
Color darken(double amount) {
final hsl = HSLColor.fromColor(this);
return hsl
.withLightness((hsl.lightness - amount).clamp(0.0, 1.0))
.toColor();
}
}
+30
View File
@@ -0,0 +1,30 @@
/// 存储键常量
class StorageKeys {
// 设置相关
static const String themeMode = 'theme_mode';
static const String customBaseUrl = 'custom_base_url';
static const String servers = 'flutter_servers';
static const String lastSelectedServer = 'last_selected_server_label';
// 上传相关
static const String uploadQueue = 'upload_queue';
static const String uploadTasks = 'upload_tasks';
// 下载相关
static const String downloadTasks = 'download_tasks';
static const String downloadWifiOnly = 'download_wifi_only';
static const String downloadRetries = 'download_retries';
// 任务记录
static const String taskRetentionDays = 'task_retention_days';
// 缓存相关
static const String cacheSettings = 'cache_settings';
// Gravatar 镜像
static const String gravatarMirrorEnabled = 'gravatar_mirror_enabled';
static const String gravatarMirrorUrl = 'gravatar_mirror_url';
// 搜索历史
static const String searchHistory = 'search_history';
}