Compare commits

..
8 Commits
Author SHA1 Message Date
Li Wei 21ec1e4539 fix: follow android 11 storage permissions (#66) 2022-12-16 21:43:06 +08:00
levi dda44cc770 fix: docker tag 2022-12-16 15:24:41 +08:00
levi 78911b2aa9 ci: fix docker build 2022-12-16 15:10:34 +08:00
Li Wei 4935dcd0e6 ci: fix 2022-12-16 15:02:33 +08:00
Li Wei e8fe6ad550 ci: docker supports more platforms (#64) 2022-12-16 14:56:56 +08:00
Li Wei db4003ad4f fix: speed calculate (#63) 2022-12-16 14:53:07 +08:00
Li Wei 0a4be165a5 fix: http download fail (#61) 2022-12-14 12:12:39 +08:00
levi c62867e3ef chore: fix docker-compose command 2022-12-13 15:00:32 +08:00
27 changed files with 193 additions and 164 deletions

No files matched your search

+2 -2
View File
@@ -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:
+21 -8
View File
@@ -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 }}
+1 -1
View File
@@ -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
View File
@@ -62,7 +62,7 @@ services:
输入以下指令启动容器: 输入以下指令启动容器:
```bash ```bash
docker compose up -d docker-compose up -d
``` ```
#### 访问服务 #### 访问服务
+1 -1
View File
@@ -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 {
+9 -5
View File
@@ -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 {
+3 -1
View File
@@ -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)
+1 -1
View File
@@ -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
} }
+15 -4
View File
@@ -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>
+3 -1
View File
@@ -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;
} }
+13 -1
View File
@@ -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);
}
+24 -5
View File
@@ -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,
}; };
+16 -2
View File
@@ -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);
}
+13 -2
View File
@@ -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,
};
+9 -9
View File
@@ -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);
} }
+9 -19
View File
@@ -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,
+9 -17
View File
@@ -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 ?? "./";
}
} }
} }
+7
View File
@@ -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,
); );
} }
+9 -8
View File
@@ -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(
+8 -10
View File
@@ -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(
+7 -6
View File
@@ -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
View File
@@ -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:
+3 -3
View File
@@ -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