import 'package:json_annotation/json_annotation.dart'; part 'downloader_config.g.dart'; @JsonSerializable(explicitToJson: true) class DownloaderConfig { String downloadDir; int maxRunning; ProtocolConfig protocolConfig = ProtocolConfig(); ExtraConfig extra = ExtraConfig(); ProxyConfig proxy = ProxyConfig(); WebhookConfig webhook = WebhookConfig(); ScriptConfig script = ScriptConfig(); AutoTorrentConfig autoTorrent = AutoTorrentConfig(); ArchiveConfig archive = ArchiveConfig(); bool autoStartTasks; bool autoDeleteMissingFileTasks; DownloaderConfig({ this.downloadDir = '', this.maxRunning = 0, this.autoStartTasks = false, this.autoDeleteMissingFileTasks = false, }); factory DownloaderConfig.fromJson(Map json) => _$DownloaderConfigFromJson(json); Map toJson() => _$DownloaderConfigToJson(this); } @JsonSerializable(explicitToJson: true) class ProtocolConfig { HttpConfig http = HttpConfig(); BtConfig bt = BtConfig(); Ed2kConfig ed2k = Ed2kConfig(); ProtocolConfig(); factory ProtocolConfig.fromJson(Map? json) => json == null ? ProtocolConfig() : _$ProtocolConfigFromJson(json); Map toJson() => _$ProtocolConfigToJson(this); } @JsonSerializable() class HttpConfig { String userAgent; int connections; bool useServerCtime; HttpConfig({ this.userAgent = '', this.connections = 0, this.useServerCtime = false, }); factory HttpConfig.fromJson(Map json) => _$HttpConfigFromJson(json); Map toJson() => _$HttpConfigToJson(this); } @JsonSerializable() class BtConfig { int listenPort; List trackers; bool seedKeep; double seedRatio; int seedTime; BtConfig({ this.listenPort = 0, this.trackers = const [], this.seedKeep = false, this.seedRatio = 0, this.seedTime = 0, }); factory BtConfig.fromJson(Map json) => _$BtConfigFromJson(json); Map toJson() => _$BtConfigToJson(this); } @JsonSerializable() class Ed2kConfig { int listenPort; int udpPort; String serverAddr; String serverMet; String nodesDat; Ed2kConfig({ this.listenPort = 0, this.udpPort = 0, this.serverAddr = '', this.serverMet = '', this.nodesDat = '', }); factory Ed2kConfig.fromJson(Map json) => _$Ed2kConfigFromJson(json); Map toJson() => _$Ed2kConfigToJson(this); } @JsonSerializable(explicitToJson: true) class ExtraConfig { String themeMode; String locale; bool lastDeleteTaskKeep; bool defaultDirectDownload; bool defaultBtClient; bool notifyWhenNewVersion; bool desktopNotification; bool backgroundLocationKeepAlive; List downloadCategories; ExtraConfigBt bt = ExtraConfigBt(); ExtraConfigGithubMirror githubMirror = ExtraConfigGithubMirror(); ExtraConfig({ this.themeMode = '', this.locale = '', this.lastDeleteTaskKeep = false, this.defaultDirectDownload = false, this.defaultBtClient = true, this.notifyWhenNewVersion = true, this.desktopNotification = true, this.backgroundLocationKeepAlive = false, this.downloadCategories = const [], }); factory ExtraConfig.fromJson(Map? json) => json == null ? ExtraConfig() : _$ExtraConfigFromJson(json); Map toJson() => _$ExtraConfigToJson(this); } @JsonSerializable() class DownloadCategory { String name; String path; bool isBuiltIn; String? nameKey; // i18n key for built-in categories (e.g., 'categoryMusic') bool isDeleted; // Mark built-in categories as deleted instead of removing them DownloadCategory({ required this.name, required this.path, this.isBuiltIn = false, this.nameKey, this.isDeleted = false, }); factory DownloadCategory.fromJson(Map json) => _$DownloadCategoryFromJson(json); Map toJson() => _$DownloadCategoryToJson(this); } @JsonSerializable() class WebhookConfig { bool enable; List urls; WebhookConfig({ this.enable = false, this.urls = const [], }); factory WebhookConfig.fromJson(Map? json) => json == null ? WebhookConfig() : _$WebhookConfigFromJson(json); Map toJson() => _$WebhookConfigToJson(this); } @JsonSerializable() class ScriptConfig { bool enable; List paths; ScriptConfig({ this.enable = false, this.paths = const [], }); factory ScriptConfig.fromJson(Map? json) => json == null ? ScriptConfig() : _$ScriptConfigFromJson(json); Map toJson() => _$ScriptConfigToJson(this); } @JsonSerializable() class ProxyConfig { bool enable; bool system; String scheme; String host; String usr; String pwd; ProxyConfig({ this.enable = false, this.system = false, this.scheme = '', this.host = '', this.usr = '', this.pwd = '', }); factory ProxyConfig.fromJson(Map json) => _$ProxyConfigFromJson(json); Map toJson() => _$ProxyConfigToJson(this); } @JsonSerializable() class ExtraConfigBt { List trackerSubscribeUrls = []; List subscribeTrackers = []; bool autoUpdateTrackers = true; DateTime? lastTrackerUpdateTime; List customTrackers = []; ExtraConfigBt(); factory ExtraConfigBt.fromJson(Map json) => _$ExtraConfigBtFromJson(json); Map toJson() => _$ExtraConfigBtToJson(this); } enum GithubMirrorType { jsdelivr, ghProxy, } @JsonSerializable() class GithubMirror { GithubMirrorType type; String url; bool isBuiltIn; bool isDeleted; GithubMirror({ required this.type, required this.url, this.isBuiltIn = false, this.isDeleted = false, }); factory GithubMirror.fromJson(Map json) => _$GithubMirrorFromJson(json); Map toJson() => _$GithubMirrorToJson(this); } @JsonSerializable(explicitToJson: true) class ExtraConfigGithubMirror { bool enabled; List mirrors; ExtraConfigGithubMirror({ this.enabled = true, this.mirrors = const [], }); factory ExtraConfigGithubMirror.fromJson(Map? json) => json == null ? ExtraConfigGithubMirror() : _$ExtraConfigGithubMirrorFromJson(json); Map toJson() => _$ExtraConfigGithubMirrorToJson(this); } @JsonSerializable() class AutoTorrentConfig { bool enable; bool deleteAfterDownload; AutoTorrentConfig({ this.enable = false, this.deleteAfterDownload = false, }); factory AutoTorrentConfig.fromJson(Map? json) => json == null ? AutoTorrentConfig() : _$AutoTorrentConfigFromJson(json); Map toJson() => _$AutoTorrentConfigToJson(this); } @JsonSerializable() class ArchiveConfig { bool autoExtract; bool deleteAfterExtract; ArchiveConfig({ this.autoExtract = true, this.deleteAfterExtract = true, }); factory ArchiveConfig.fromJson(Map? json) => json == null ? ArchiveConfig() : _$ArchiveConfigFromJson(json); Map toJson() => _$ArchiveConfigToJson(this); }