diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 67b5f0e1..79522326 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -1,5 +1,5 @@ -name-template: 'v1.2.0 🌈' -tag-template: 'v1.2.0' +name-template: 'v$NEXT_PATCH_VERSION 🌈' +tag-template: 'v$NEXT_PATCH_VERSION' categories: - title: '🆕 Features' labels: diff --git a/internal/protocol/http/fetcher.go b/internal/protocol/http/fetcher.go index f699f76d..c65a5cd5 100644 --- a/internal/protocol/http/fetcher.go +++ b/internal/protocol/http/fetcher.go @@ -151,7 +151,7 @@ func (f *Fetcher) Create(res *base.Resource, opts *base.Options) error { return err } if opts.Extra == nil { - opts.Extra = &fhttp.ReqExtra{} + opts.Extra = &fhttp.OptsExtra{} } extra := opts.Extra.(*fhttp.OptsExtra) if extra.Connections == 0 { diff --git a/internal/protocol/http/fetcher_test.go b/internal/protocol/http/fetcher_test.go index bd703c57..cb3387f2 100644 --- a/internal/protocol/http/fetcher_test.go +++ b/internal/protocol/http/fetcher_test.go @@ -142,12 +142,16 @@ func doDownloadReady(f fetcher.Fetcher, listener net.Listener, connections int, if err != nil { t.Fatal(err) } - opts = &base.Options{ - Name: test.DownloadName, - Path: test.Dir, - Extra: http.OptsExtra{ + var extra any = nil + if connections > 0 { + extra = http.OptsExtra{ Connections: connections, - }, + } + } + opts = &base.Options{ + Name: test.DownloadName, + Path: test.Dir, + Extra: extra, } err = fetcher.Create(res, opts) if err != nil { diff --git a/pkg/download/downloader.go b/pkg/download/downloader.go index 1c62f092..ee7289da 100644 --- a/pkg/download/downloader.go +++ b/pkg/download/downloader.go @@ -102,7 +102,14 @@ func (d *Downloader) Setup() error { current := task.fetcher.Progress().TotalDownloaded() task.Progress.Used = task.timer.Used() - task.Progress.Speed = current - task.Progress.Downloaded + downloaded := current - task.Progress.Downloaded + usedTime := float64(d.refreshInterval) / 1000 + if downloaded == 0 { + task.Progress.Speed = int64(float64(task.Progress.Speed) / (usedTime * 1.55)) + } else { + usedTime := float64(d.refreshInterval) / 1000 + task.Progress.Speed = int64(float64(current-task.Progress.Downloaded) / usedTime) + } task.Progress.Downloaded = current d.emit(EventKeyProgress, task) diff --git a/pkg/download/model.go b/pkg/download/model.go index 08a9733d..e5c887d7 100644 --- a/pkg/download/model.go +++ b/pkg/download/model.go @@ -34,7 +34,7 @@ func (cfg *DownloaderConfig) Init() *DownloaderConfig { } if cfg.RefreshInterval == 0 { - cfg.RefreshInterval = 1000 + cfg.RefreshInterval = 500 } return cfg } diff --git a/ui/flutter/android/app/build.gradle b/ui/flutter/android/app/build.gradle index 04721767..9fd7e9fe 100644 --- a/ui/flutter/android/app/build.gradle +++ b/ui/flutter/android/app/build.gradle @@ -48,7 +48,7 @@ android { // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion 19 - targetSdkVersion flutter.targetSdkVersion + targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/ui/flutter/lib/api/model/create_task.dart b/ui/flutter/lib/api/model/create_task.dart index c874b467..94b3d8b1 100644 --- a/ui/flutter/lib/api/model/create_task.dart +++ b/ui/flutter/lib/api/model/create_task.dart @@ -15,7 +15,9 @@ class CreateTask { this.opts, }); - factory CreateTask.fromJson(Map json) => + factory CreateTask.fromJson( + Map json, + ) => _$CreateTaskFromJson(json); Map toJson() => _$CreateTaskToJson(this); diff --git a/ui/flutter/lib/api/model/downloader_config.g.dart b/ui/flutter/lib/api/model/downloader_config.g.dart index 7e941e60..9c6fe5fb 100644 --- a/ui/flutter/lib/api/model/downloader_config.g.dart +++ b/ui/flutter/lib/api/model/downloader_config.g.dart @@ -64,12 +64,12 @@ ExtraConfigBt _$ExtraConfigBtFromJson(Map json) => ..trackerSubscribeUrls = (json['trackerSubscribeUrls'] as List) .map((e) => e as String) .toList() - ..lastTrackerUpdateTime = json['lastTrackerUpdateTime'] == null - ? null - : DateTime.parse(json['lastTrackerUpdateTime'] as String) ..subscribeTrackers = (json['subscribeTrackers'] as List) .map((e) => e as String) .toList() + ..lastTrackerUpdateTime = json['lastTrackerUpdateTime'] == null + ? null + : DateTime.parse(json['lastTrackerUpdateTime'] as String) ..customTrackers = (json['customTrackers'] as List) .map((e) => e as String) .toList(); @@ -77,6 +77,7 @@ ExtraConfigBt _$ExtraConfigBtFromJson(Map json) => Map _$ExtraConfigBtToJson(ExtraConfigBt instance) { final val = { 'trackerSubscribeUrls': instance.trackerSubscribeUrls, + 'subscribeTrackers': instance.subscribeTrackers, }; void writeNotNull(String key, dynamic value) { @@ -87,7 +88,6 @@ Map _$ExtraConfigBtToJson(ExtraConfigBt instance) { writeNotNull('lastTrackerUpdateTime', instance.lastTrackerUpdateTime?.toIso8601String()); - val['subscribeTrackers'] = instance.subscribeTrackers; val['customTrackers'] = instance.customTrackers; return val; } diff --git a/ui/flutter/lib/api/model/options.dart b/ui/flutter/lib/api/model/options.dart index e8bb5b0a..1b50d37d 100644 --- a/ui/flutter/lib/api/model/options.dart +++ b/ui/flutter/lib/api/model/options.dart @@ -2,11 +2,12 @@ import 'package:json_annotation/json_annotation.dart'; part 'options.g.dart'; -@JsonSerializable() +@JsonSerializable(explicitToJson: true, genericArgumentFactories: true) class Options { String name; String path; List selectFiles; + Map? extra; Options({ required this.name, @@ -19,3 +20,14 @@ class Options { Map toJson() => _$OptionsToJson(this); } + +@JsonSerializable() +class OptsExtraHttp { + int connections = 0; + + OptsExtraHttp(); + + factory OptsExtraHttp.fromJson(Map json) => + _$OptsExtraHttpFromJson(json); + Map toJson() => _$OptsExtraHttpToJson(this); +} diff --git a/ui/flutter/lib/api/model/options.g.dart b/ui/flutter/lib/api/model/options.g.dart index 4327f40e..6562554e 100644 --- a/ui/flutter/lib/api/model/options.g.dart +++ b/ui/flutter/lib/api/model/options.g.dart @@ -11,10 +11,29 @@ Options _$OptionsFromJson(Map json) => Options( path: json['path'] as String, selectFiles: (json['selectFiles'] as List).map((e) => e as int).toList(), - ); + )..extra = json['extra'] as Map?; -Map _$OptionsToJson(Options instance) => { - 'name': instance.name, - 'path': instance.path, - 'selectFiles': instance.selectFiles, +Map _$OptionsToJson(Options instance) { + final val = { + 'name': instance.name, + 'path': instance.path, + 'selectFiles': instance.selectFiles, + }; + + void writeNotNull(String key, dynamic value) { + if (value != null) { + val[key] = value; + } + } + + writeNotNull('extra', instance.extra); + return val; +} + +OptsExtraHttp _$OptsExtraHttpFromJson(Map json) => + OptsExtraHttp()..connections = json['connections'] as int; + +Map _$OptsExtraHttpToJson(OptsExtraHttp instance) => + { + 'connections': instance.connections, }; diff --git a/ui/flutter/lib/api/model/request.dart b/ui/flutter/lib/api/model/request.dart index 7bcc0fe2..cb67416c 100644 --- a/ui/flutter/lib/api/model/request.dart +++ b/ui/flutter/lib/api/model/request.dart @@ -2,17 +2,31 @@ import 'package:json_annotation/json_annotation.dart'; part 'request.g.dart'; -@JsonSerializable() +@JsonSerializable(explicitToJson: true, genericArgumentFactories: true) class Request { String url; Map? extra; Request({ required this.url, - this.extra, }); factory Request.fromJson(Map json) => _$RequestFromJson(json); + Map toJson() => _$RequestToJson(this); } + +@JsonSerializable() +class ReqExtraHttp { + String method = 'GET'; + Map headers = {}; + String body = ''; + + ReqExtraHttp(); + + factory ReqExtraHttp.fromJson(Map json) => + _$ReqExtraHttpFromJson(json); + + Map toJson() => _$ReqExtraHttpToJson(this); +} diff --git a/ui/flutter/lib/api/model/request.g.dart b/ui/flutter/lib/api/model/request.g.dart index a4e60d1b..8e221e84 100644 --- a/ui/flutter/lib/api/model/request.g.dart +++ b/ui/flutter/lib/api/model/request.g.dart @@ -8,8 +8,7 @@ part of 'request.dart'; Request _$RequestFromJson(Map json) => Request( url: json['url'] as String, - extra: json['extra'] as Map?, - ); + )..extra = json['extra'] as Map?; Map _$RequestToJson(Request instance) { final val = { @@ -25,3 +24,15 @@ Map _$RequestToJson(Request instance) { writeNotNull('extra', instance.extra); return val; } + +ReqExtraHttp _$ReqExtraHttpFromJson(Map json) => ReqExtraHttp() + ..method = json['method'] as String + ..headers = Map.from(json['headers'] as Map) + ..body = json['body'] as String; + +Map _$ReqExtraHttpToJson(ReqExtraHttp instance) => + { + 'method': instance.method, + 'headers': instance.headers, + 'body': instance.body, + }; diff --git a/ui/flutter/lib/api/model/resource.dart b/ui/flutter/lib/api/model/resource.dart index 7d2d3ad2..4b73c46e 100644 --- a/ui/flutter/lib/api/model/resource.dart +++ b/ui/flutter/lib/api/model/resource.dart @@ -11,19 +11,19 @@ class Resource { int size; bool range; List files; - Map? extra; + String hash; - Resource({ - required this.req, - required this.name, - required this.size, - required this.range, - required this.files, - this.extra, - }); + Resource( + {required this.req, + required this.name, + required this.size, + required this.range, + required this.files, + required this.hash}); factory Resource.fromJson(Map json) => _$ResourceFromJson(json); + Map toJson() => _$ResourceToJson(this); } diff --git a/ui/flutter/lib/api/model/resource.g.dart b/ui/flutter/lib/api/model/resource.g.dart index 5c57df2d..eab7a7c3 100644 --- a/ui/flutter/lib/api/model/resource.g.dart +++ b/ui/flutter/lib/api/model/resource.g.dart @@ -14,27 +14,17 @@ Resource _$ResourceFromJson(Map json) => Resource( files: (json['files'] as List) .map((e) => FileInfo.fromJson(e as Map)) .toList(), - extra: json['extra'] as Map?, + hash: json['hash'] as String, ); -Map _$ResourceToJson(Resource instance) { - final val = { - 'req': instance.req.toJson(), - 'name': instance.name, - 'size': instance.size, - 'range': instance.range, - 'files': instance.files.map((e) => e.toJson()).toList(), - }; - - void writeNotNull(String key, dynamic value) { - if (value != null) { - val[key] = value; - } - } - - writeNotNull('extra', instance.extra); - return val; -} +Map _$ResourceToJson(Resource instance) => { + 'req': instance.req.toJson(), + 'name': instance.name, + 'size': instance.size, + 'range': instance.range, + 'files': instance.files.map((e) => e.toJson()).toList(), + 'hash': instance.hash, + }; FileInfo _$FileInfoFromJson(Map json) => FileInfo( name: json['name'] as String,