mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-11 02:50:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21ec1e4539 | ||
|
|
dda44cc770 | ||
|
|
78911b2aa9 | ||
|
|
4935dcd0e6 | ||
|
|
e8fe6ad550 | ||
|
|
db4003ad4f | ||
|
|
0a4be165a5 | ||
|
|
c62867e3ef |
No files matched your search
@@ -1,5 +1,5 @@
|
|||||||
name-template: 'v1.2.0 🌈'
|
name-template: 'v$NEXT_PATCH_VERSION 🌈'
|
||||||
tag-template: 'v1.2.0'
|
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||||
categories:
|
categories:
|
||||||
- title: '🆕 Features'
|
- title: '🆕 Features'
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -268,6 +268,7 @@ jobs:
|
|||||||
gomobile init
|
gomobile init
|
||||||
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg=com.gopeed github.com/monkeyWie/gopeed/bind/mobile
|
gomobile bind -tags nosqlite -ldflags="-w -s" -o ui/flutter/android/app/libs/libgopeed.aar -target=android -androidapi 19 -javapkg=com.gopeed github.com/monkeyWie/gopeed/bind/mobile
|
||||||
cd ui/flutter
|
cd ui/flutter
|
||||||
|
echo $APK_KEYSTORE | base64 -d > android/app/upload-keystore.jks
|
||||||
flutter build apk
|
flutter build apk
|
||||||
mkdir dist
|
mkdir dist
|
||||||
cp build/app/outputs/flutter-apk/app-release.apk dist/Gopeed-$VERSION-android.apk
|
cp build/app/outputs/flutter-apk/app-release.apk dist/Gopeed-$VERSION-android.apk
|
||||||
@@ -324,13 +325,25 @@ jobs:
|
|||||||
needs: [get-release]
|
needs: [get-release]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Build
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: liwei2633
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
env:
|
env:
|
||||||
VERSION: ${{ needs.get-release.outputs.tag_name }}
|
VERSION: ${{ needs.get-release.outputs.tag_name }}
|
||||||
run: |
|
with:
|
||||||
tag=liwei2633/gopeed:${VERSION:1}
|
push: true
|
||||||
docker build -t $tag .
|
platforms: |
|
||||||
docker login -u liwei2633 -p ${{ secrets.DOCKER_PASSWORD }}
|
linux/386
|
||||||
docker push $tag
|
linux/amd64
|
||||||
docker tag $tag liwei2633/gopeed:latest
|
linux/arm64
|
||||||
docker push liwei2633/gopeed:latest
|
tags: |
|
||||||
|
liwei2633/gopeed:latest
|
||||||
|
liwei2633/gopeed:${{ env.VERSION }}
|
||||||
@@ -62,7 +62,7 @@ services:
|
|||||||
Use the command below to start container:
|
Use the command below to start container:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Access Gopeed
|
#### Access Gopeed
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ services:
|
|||||||
输入以下指令启动容器:
|
输入以下指令启动容器:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 访问服务
|
#### 访问服务
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ func (f *Fetcher) Create(res *base.Resource, opts *base.Options) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if opts.Extra == nil {
|
if opts.Extra == nil {
|
||||||
opts.Extra = &fhttp.ReqExtra{}
|
opts.Extra = &fhttp.OptsExtra{}
|
||||||
}
|
}
|
||||||
extra := opts.Extra.(*fhttp.OptsExtra)
|
extra := opts.Extra.(*fhttp.OptsExtra)
|
||||||
if extra.Connections == 0 {
|
if extra.Connections == 0 {
|
||||||
|
|||||||
@@ -142,12 +142,16 @@ func doDownloadReady(f fetcher.Fetcher, listener net.Listener, connections int,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
opts = &base.Options{
|
var extra any = nil
|
||||||
Name: test.DownloadName,
|
if connections > 0 {
|
||||||
Path: test.Dir,
|
extra = http.OptsExtra{
|
||||||
Extra: http.OptsExtra{
|
|
||||||
Connections: connections,
|
Connections: connections,
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
opts = &base.Options{
|
||||||
|
Name: test.DownloadName,
|
||||||
|
Path: test.Dir,
|
||||||
|
Extra: extra,
|
||||||
}
|
}
|
||||||
err = fetcher.Create(res, opts)
|
err = fetcher.Create(res, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -102,7 +102,9 @@ func (d *Downloader) Setup() error {
|
|||||||
|
|
||||||
current := task.fetcher.Progress().TotalDownloaded()
|
current := task.fetcher.Progress().TotalDownloaded()
|
||||||
task.Progress.Used = task.timer.Used()
|
task.Progress.Used = task.timer.Used()
|
||||||
task.Progress.Speed = current - task.Progress.Downloaded
|
currUsedTime := float64(d.refreshInterval) / 1000
|
||||||
|
currSpeed := int64(float64(current-task.Progress.Downloaded) / currUsedTime)
|
||||||
|
task.Progress.Speed = (task.Progress.Speed + currSpeed) / 2
|
||||||
task.Progress.Downloaded = current
|
task.Progress.Downloaded = current
|
||||||
d.emit(EventKeyProgress, task)
|
d.emit(EventKeyProgress, task)
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func (cfg *DownloaderConfig) Init() *DownloaderConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.RefreshInterval == 0 {
|
if cfg.RefreshInterval == 0 {
|
||||||
cfg.RefreshInterval = 1000
|
cfg.RefreshInterval = 350
|
||||||
}
|
}
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,16 +48,27 @@ android {
|
|||||||
// You can update the following values to match your application needs.
|
// 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.
|
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion 29
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
keyAlias "upload"
|
||||||
|
keyPassword System.getenv("APK_KEY_PASSWORD")
|
||||||
|
storeFile file("upload-keystore.jks")
|
||||||
|
storePassword System.getenv("APK_STORE_PASSWORD")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
if (signingConfigs.release.keyPassword != null) {
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
signingConfig signingConfigs.release
|
||||||
signingConfig signingConfigs.debug
|
} else {
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,5 @@
|
|||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<application android:requestLegacyExternalStorage="true"/>
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -2,11 +2,8 @@
|
|||||||
package="com.gopeed">
|
package="com.gopeed">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:requestLegacyExternalStorage="true"
|
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="Gopeed">
|
android:label="Gopeed">
|
||||||
|
|||||||
@@ -4,9 +4,5 @@
|
|||||||
the Flutter tool needs it to communicate with the running application
|
the Flutter tool needs it to communicate with the running application
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<application android:requestLegacyExternalStorage="true"/>
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -15,7 +15,9 @@ class CreateTask {
|
|||||||
this.opts,
|
this.opts,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory CreateTask.fromJson(Map<String, dynamic> json) =>
|
factory CreateTask.fromJson(
|
||||||
|
Map<String, dynamic> json,
|
||||||
|
) =>
|
||||||
_$CreateTaskFromJson(json);
|
_$CreateTaskFromJson(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$CreateTaskToJson(this);
|
Map<String, dynamic> toJson() => _$CreateTaskToJson(this);
|
||||||
|
|||||||
@@ -64,12 +64,12 @@ ExtraConfigBt _$ExtraConfigBtFromJson(Map<String, dynamic> json) =>
|
|||||||
..trackerSubscribeUrls = (json['trackerSubscribeUrls'] as List<dynamic>)
|
..trackerSubscribeUrls = (json['trackerSubscribeUrls'] as List<dynamic>)
|
||||||
.map((e) => e as String)
|
.map((e) => e as String)
|
||||||
.toList()
|
.toList()
|
||||||
..lastTrackerUpdateTime = json['lastTrackerUpdateTime'] == null
|
|
||||||
? null
|
|
||||||
: DateTime.parse(json['lastTrackerUpdateTime'] as String)
|
|
||||||
..subscribeTrackers = (json['subscribeTrackers'] as List<dynamic>)
|
..subscribeTrackers = (json['subscribeTrackers'] as List<dynamic>)
|
||||||
.map((e) => e as String)
|
.map((e) => e as String)
|
||||||
.toList()
|
.toList()
|
||||||
|
..lastTrackerUpdateTime = json['lastTrackerUpdateTime'] == null
|
||||||
|
? null
|
||||||
|
: DateTime.parse(json['lastTrackerUpdateTime'] as String)
|
||||||
..customTrackers = (json['customTrackers'] as List<dynamic>)
|
..customTrackers = (json['customTrackers'] as List<dynamic>)
|
||||||
.map((e) => e as String)
|
.map((e) => e as String)
|
||||||
.toList();
|
.toList();
|
||||||
@@ -77,6 +77,7 @@ ExtraConfigBt _$ExtraConfigBtFromJson(Map<String, dynamic> json) =>
|
|||||||
Map<String, dynamic> _$ExtraConfigBtToJson(ExtraConfigBt instance) {
|
Map<String, dynamic> _$ExtraConfigBtToJson(ExtraConfigBt instance) {
|
||||||
final val = <String, dynamic>{
|
final val = <String, dynamic>{
|
||||||
'trackerSubscribeUrls': instance.trackerSubscribeUrls,
|
'trackerSubscribeUrls': instance.trackerSubscribeUrls,
|
||||||
|
'subscribeTrackers': instance.subscribeTrackers,
|
||||||
};
|
};
|
||||||
|
|
||||||
void writeNotNull(String key, dynamic value) {
|
void writeNotNull(String key, dynamic value) {
|
||||||
@@ -87,7 +88,6 @@ Map<String, dynamic> _$ExtraConfigBtToJson(ExtraConfigBt instance) {
|
|||||||
|
|
||||||
writeNotNull('lastTrackerUpdateTime',
|
writeNotNull('lastTrackerUpdateTime',
|
||||||
instance.lastTrackerUpdateTime?.toIso8601String());
|
instance.lastTrackerUpdateTime?.toIso8601String());
|
||||||
val['subscribeTrackers'] = instance.subscribeTrackers;
|
|
||||||
val['customTrackers'] = instance.customTrackers;
|
val['customTrackers'] = instance.customTrackers;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,12 @@ import 'package:json_annotation/json_annotation.dart';
|
|||||||
|
|
||||||
part 'options.g.dart';
|
part 'options.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable(explicitToJson: true, genericArgumentFactories: true)
|
||||||
class Options {
|
class Options {
|
||||||
String name;
|
String name;
|
||||||
String path;
|
String path;
|
||||||
List<int> selectFiles;
|
List<int> selectFiles;
|
||||||
|
Map<String, dynamic>? extra;
|
||||||
|
|
||||||
Options({
|
Options({
|
||||||
required this.name,
|
required this.name,
|
||||||
@@ -19,3 +20,14 @@ class Options {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() => _$OptionsToJson(this);
|
Map<String, dynamic> toJson() => _$OptionsToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class OptsExtraHttp {
|
||||||
|
int connections = 0;
|
||||||
|
|
||||||
|
OptsExtraHttp();
|
||||||
|
|
||||||
|
factory OptsExtraHttp.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$OptsExtraHttpFromJson(json);
|
||||||
|
Map<String, dynamic> toJson() => _$OptsExtraHttpToJson(this);
|
||||||
|
}
|
||||||
@@ -11,10 +11,29 @@ Options _$OptionsFromJson(Map<String, dynamic> json) => Options(
|
|||||||
path: json['path'] as String,
|
path: json['path'] as String,
|
||||||
selectFiles:
|
selectFiles:
|
||||||
(json['selectFiles'] as List<dynamic>).map((e) => e as int).toList(),
|
(json['selectFiles'] as List<dynamic>).map((e) => e as int).toList(),
|
||||||
);
|
)..extra = json['extra'] as Map<String, dynamic>?;
|
||||||
|
|
||||||
Map<String, dynamic> _$OptionsToJson(Options instance) => <String, dynamic>{
|
Map<String, dynamic> _$OptionsToJson(Options instance) {
|
||||||
'name': instance.name,
|
final val = <String, dynamic>{
|
||||||
'path': instance.path,
|
'name': instance.name,
|
||||||
'selectFiles': instance.selectFiles,
|
'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<String, dynamic> json) =>
|
||||||
|
OptsExtraHttp()..connections = json['connections'] as int;
|
||||||
|
|
||||||
|
Map<String, dynamic> _$OptsExtraHttpToJson(OptsExtraHttp instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'connections': instance.connections,
|
||||||
};
|
};
|
||||||
@@ -2,17 +2,31 @@ import 'package:json_annotation/json_annotation.dart';
|
|||||||
|
|
||||||
part 'request.g.dart';
|
part 'request.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable(explicitToJson: true, genericArgumentFactories: true)
|
||||||
class Request {
|
class Request {
|
||||||
String url;
|
String url;
|
||||||
Map<String, dynamic>? extra;
|
Map<String, dynamic>? extra;
|
||||||
|
|
||||||
Request({
|
Request({
|
||||||
required this.url,
|
required this.url,
|
||||||
this.extra,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
factory Request.fromJson(Map<String, dynamic> json) =>
|
factory Request.fromJson(Map<String, dynamic> json) =>
|
||||||
_$RequestFromJson(json);
|
_$RequestFromJson(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$RequestToJson(this);
|
Map<String, dynamic> toJson() => _$RequestToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class ReqExtraHttp {
|
||||||
|
String method = 'GET';
|
||||||
|
Map<String, String> headers = {};
|
||||||
|
String body = '';
|
||||||
|
|
||||||
|
ReqExtraHttp();
|
||||||
|
|
||||||
|
factory ReqExtraHttp.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$ReqExtraHttpFromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$ReqExtraHttpToJson(this);
|
||||||
|
}
|
||||||
@@ -8,8 +8,7 @@ part of 'request.dart';
|
|||||||
|
|
||||||
Request _$RequestFromJson(Map<String, dynamic> json) => Request(
|
Request _$RequestFromJson(Map<String, dynamic> json) => Request(
|
||||||
url: json['url'] as String,
|
url: json['url'] as String,
|
||||||
extra: json['extra'] as Map<String, dynamic>?,
|
)..extra = json['extra'] as Map<String, dynamic>?;
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$RequestToJson(Request instance) {
|
Map<String, dynamic> _$RequestToJson(Request instance) {
|
||||||
final val = <String, dynamic>{
|
final val = <String, dynamic>{
|
||||||
@@ -25,3 +24,15 @@ Map<String, dynamic> _$RequestToJson(Request instance) {
|
|||||||
writeNotNull('extra', instance.extra);
|
writeNotNull('extra', instance.extra);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReqExtraHttp _$ReqExtraHttpFromJson(Map<String, dynamic> json) => ReqExtraHttp()
|
||||||
|
..method = json['method'] as String
|
||||||
|
..headers = Map<String, String>.from(json['headers'] as Map)
|
||||||
|
..body = json['body'] as String;
|
||||||
|
|
||||||
|
Map<String, dynamic> _$ReqExtraHttpToJson(ReqExtraHttp instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'method': instance.method,
|
||||||
|
'headers': instance.headers,
|
||||||
|
'body': instance.body,
|
||||||
|
};
|
||||||
@@ -11,19 +11,19 @@ class Resource {
|
|||||||
int size;
|
int size;
|
||||||
bool range;
|
bool range;
|
||||||
List<FileInfo> files;
|
List<FileInfo> files;
|
||||||
Map<String, dynamic>? extra;
|
String hash;
|
||||||
|
|
||||||
Resource({
|
Resource(
|
||||||
required this.req,
|
{required this.req,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.size,
|
required this.size,
|
||||||
required this.range,
|
required this.range,
|
||||||
required this.files,
|
required this.files,
|
||||||
this.extra,
|
required this.hash});
|
||||||
});
|
|
||||||
|
|
||||||
factory Resource.fromJson(Map<String, dynamic> json) =>
|
factory Resource.fromJson(Map<String, dynamic> json) =>
|
||||||
_$ResourceFromJson(json);
|
_$ResourceFromJson(json);
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$ResourceToJson(this);
|
Map<String, dynamic> toJson() => _$ResourceToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,27 +14,17 @@ Resource _$ResourceFromJson(Map<String, dynamic> json) => Resource(
|
|||||||
files: (json['files'] as List<dynamic>)
|
files: (json['files'] as List<dynamic>)
|
||||||
.map((e) => FileInfo.fromJson(e as Map<String, dynamic>))
|
.map((e) => FileInfo.fromJson(e as Map<String, dynamic>))
|
||||||
.toList(),
|
.toList(),
|
||||||
extra: json['extra'] as Map<String, dynamic>?,
|
hash: json['hash'] as String,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$ResourceToJson(Resource instance) {
|
Map<String, dynamic> _$ResourceToJson(Resource instance) => <String, dynamic>{
|
||||||
final val = <String, dynamic>{
|
'req': instance.req.toJson(),
|
||||||
'req': instance.req.toJson(),
|
'name': instance.name,
|
||||||
'name': instance.name,
|
'size': instance.size,
|
||||||
'size': instance.size,
|
'range': instance.range,
|
||||||
'range': instance.range,
|
'files': instance.files.map((e) => e.toJson()).toList(),
|
||||||
'files': instance.files.map((e) => e.toJson()).toList(),
|
'hash': instance.hash,
|
||||||
};
|
};
|
||||||
|
|
||||||
void writeNotNull(String key, dynamic value) {
|
|
||||||
if (value != null) {
|
|
||||||
val[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeNotNull('extra', instance.extra);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfo _$FileInfoFromJson(Map<String, dynamic> json) => FileInfo(
|
FileInfo _$FileInfoFromJson(Map<String, dynamic> json) => FileInfo(
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:external_path/external_path.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@@ -157,23 +156,16 @@ class AppController extends GetxController {
|
|||||||
extra.bt.trackerSubscribeUrls.addAll(allTrackerSubscribeUrls);
|
extra.bt.trackerSubscribeUrls.addAll(allTrackerSubscribeUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Util.isAndroid()) {
|
if (Util.isDesktop()) {
|
||||||
config.downloadDir =
|
config.downloadDir = (await getDownloadsDirectory())?.path ?? "./";
|
||||||
'${await ExternalPath.getExternalStoragePublicDirectory(ExternalPath.DIRECTORY_DOWNLOADS)}/com.gopeed';
|
} else if (Util.isAndroid()) {
|
||||||
|
config.downloadDir = (await getExternalStorageDirectory())?.path ??
|
||||||
|
(await getApplicationDocumentsDirectory()).path;
|
||||||
return;
|
return;
|
||||||
}
|
} else if (Util.isIOS()) {
|
||||||
if (Util.isIOS()) {
|
config.downloadDir = (await getApplicationDocumentsDirectory()).path;
|
||||||
config.downloadDir = 'Documents';
|
} else {
|
||||||
return;
|
config.downloadDir = './';
|
||||||
}
|
|
||||||
|
|
||||||
if (config.downloadDir.isEmpty) {
|
|
||||||
if (Util.isWeb()) {
|
|
||||||
config.downloadDir = './';
|
|
||||||
}
|
|
||||||
if (Util.isDesktop()) {
|
|
||||||
config.downloadDir = (await getDownloadsDirectory())?.path ?? "./";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../i18n/messages.dart';
|
import '../../i18n/messages.dart';
|
||||||
@@ -20,6 +21,12 @@ class AppView extends GetView<AppController> {
|
|||||||
translations: messages,
|
translations: messages,
|
||||||
locale: toLocale(config.extra.locale),
|
locale: toLocale(config.extra.locale),
|
||||||
fallbackLocale: fallbackLocale,
|
fallbackLocale: fallbackLocale,
|
||||||
|
localizationsDelegates: const [
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
],
|
||||||
|
supportedLocales: messages.keys.keys.map((e) => toLocale(e)).toList(),
|
||||||
getPages: Routes.routes,
|
getPages: Routes.routes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:desktop_drop/desktop_drop.dart';
|
import 'package:desktop_drop/desktop_drop.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
|
||||||
import 'package:rounded_loading_button/rounded_loading_button.dart';
|
import 'package:rounded_loading_button/rounded_loading_button.dart';
|
||||||
|
|
||||||
import '../../api/api.dart';
|
import '../../api/api.dart';
|
||||||
@@ -171,13 +170,15 @@ class CreateView extends GetView<CreateController> {
|
|||||||
try {
|
try {
|
||||||
if (createFormKey.currentState!.validate()) {
|
if (createFormKey.currentState!.validate()) {
|
||||||
downloadController.start();
|
downloadController.start();
|
||||||
if (Util.isAndroid()) {
|
|
||||||
if (!await Permission.storage.request().isGranted) {
|
// if (Util.isAndroid()) {
|
||||||
Get.snackbar('error'.tr,
|
// if (!await Permission.storage.request().isGranted) {
|
||||||
'create.error.noStoragePermission'.tr);
|
// Get.snackbar('error'.tr,
|
||||||
return;
|
// 'create.error.noStoragePermission'.tr);
|
||||||
}
|
// return;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
await createTask(CreateTask(
|
await createTask(CreateTask(
|
||||||
res: res,
|
res: res,
|
||||||
opts: Options(
|
opts: Options(
|
||||||
|
|||||||
@@ -135,15 +135,12 @@ class SettingView extends GetView<SettingController> {
|
|||||||
controller: trackerUpdateController,
|
controller: trackerUpdateController,
|
||||||
child: Text('setting.update'.tr),
|
child: Text('setting.update'.tr),
|
||||||
),
|
),
|
||||||
Flexible(
|
Expanded(
|
||||||
child: SizedBox(
|
child: SwitchListTile(
|
||||||
width: 200,
|
controlAffinity: ListTileControlAffinity.leading,
|
||||||
child: SwitchListTile(
|
value: true,
|
||||||
controlAffinity: ListTileControlAffinity.leading,
|
onChanged: (bool value) {},
|
||||||
value: true,
|
title: Text('setting.updateDaily'.tr)),
|
||||||
onChanged: (bool value) {},
|
|
||||||
title: Text('setting.updateDaily'.tr)),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -234,7 +231,8 @@ class SettingView extends GetView<SettingController> {
|
|||||||
title: Text('setting.homepage'.tr),
|
title: Text('setting.homepage'.tr),
|
||||||
subtitle: const Text('https://github.com/monkeyWie/gopeed'),
|
subtitle: const Text('https://github.com/monkeyWie/gopeed'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
launchUrl(Uri.parse('https://github.com/monkeyWie/gopeed'));
|
launchUrl(Uri.parse('https://github.com/monkeyWie/gopeed'),
|
||||||
|
mode: LaunchMode.externalApplication);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
buildVersion() => ListTile(
|
buildVersion() => ListTile(
|
||||||
|
|||||||
@@ -30,13 +30,14 @@ class Item extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
SizedBox(
|
||||||
|
width: 180,
|
||||||
child: Text(
|
child: Text(
|
||||||
"${isDone() ? "" : "${Util.fmtByte(task.progress.downloaded)} / "}${Util.fmtByte(task.size)}",
|
"${isDone() ? "" : "${Util.fmtByte(task.progress.downloaded)} / "}${Util.fmtByte(task.size)}",
|
||||||
style: context.textTheme.bodyText1
|
style: context.textTheme.bodyText1
|
||||||
?.copyWith(color: Get.theme.disabledColor),
|
?.copyWith(color: Get.theme.disabledColor),
|
||||||
).padding(left: 18)),
|
).padding(left: 18)),
|
||||||
Expanded(
|
Flexible(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
+5
-42
@@ -197,13 +197,6 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.6"
|
version: "4.0.6"
|
||||||
external_path:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: external_path
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.3"
|
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -309,6 +302,11 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -564,41 +562,6 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
permission_handler:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: permission_handler
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "10.1.0"
|
|
||||||
permission_handler_android:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: permission_handler_android
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "10.1.0"
|
|
||||||
permission_handler_apple:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: permission_handler_apple
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "9.0.6"
|
|
||||||
permission_handler_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: permission_handler_platform_interface
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "3.9.0"
|
|
||||||
permission_handler_windows:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: permission_handler_windows
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.1"
|
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 1.2.0+1
|
version: 1.2.3+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.17.6 <3.0.0"
|
sdk: ">=2.17.6 <3.0.0"
|
||||||
@@ -29,6 +29,8 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
@@ -46,8 +48,6 @@ dependencies:
|
|||||||
rounded_loading_button: ^2.1.0
|
rounded_loading_button: ^2.1.0
|
||||||
url_launcher: ^6.1.6
|
url_launcher: ^6.1.6
|
||||||
shared_preferences: ^2.0.15
|
shared_preferences: ^2.0.15
|
||||||
permission_handler: ^10.1.0
|
|
||||||
external_path: ^1.0.3
|
|
||||||
logger: ^1.1.0
|
logger: ^1.1.0
|
||||||
desktop_drop: ^0.3.3
|
desktop_drop: ^0.3.3
|
||||||
intl: ^0.17.0
|
intl: ^0.17.0
|
||||||
|
|||||||
Reference in new issue
Block a user