Compare commits
No commits in common. "e661171fd212d69dc147e1cab3657adf83a71dd5" and "03d61dcdd031b6d64ea05c5ad20a120cc3ff08b8" have entirely different histories.
e661171fd2
...
03d61dcdd0
11 changed files with 130 additions and 175 deletions
|
@ -2,10 +2,7 @@
|
||||||
|
|
||||||
## 1.6.2+20 - UNRELEASED
|
## 1.6.2+20 - UNRELEASED
|
||||||
* Updated internal dependencies
|
* Updated internal dependencies
|
||||||
* Moved progress indicator of _Show Configuration_ into the underlying button
|
* Move progress indicator of _Show Configuration_ into button
|
||||||
* Bumped Android minSdk to `30` (Android 11)
|
|
||||||
* Fixed permission service not handling Android SDK 33 correctly
|
|
||||||
* Fixed permission service not being started during application start
|
|
||||||
|
|
||||||
## 1.6.1+19
|
## 1.6.1+19
|
||||||
* Updated internal dependencies
|
* Updated internal dependencies
|
||||||
|
|
|
@ -39,7 +39,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "de.varakh.fbmobile"
|
applicationId "de.varakh.fbmobile"
|
||||||
minSdkVersion 30
|
minSdkVersion 19
|
||||||
targetSdkVersion 33
|
targetSdkVersion 33
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
|
|
@ -4,10 +4,7 @@
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
|
|
|
@ -30,10 +30,7 @@
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
|
|
|
@ -4,10 +4,7 @@
|
||||||
to allow setting breakpoints, to provide hot reload, etc.
|
to allow setting breakpoints, to provide hot reload, etc.
|
||||||
-->
|
-->
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
<intent>
|
<intent>
|
||||||
|
|
|
@ -126,6 +126,14 @@
|
||||||
"description": "Could not open '{link}'. Please ensure that you have an application installed which handles opening such link types."
|
"description": "Could not open '{link}'. Please ensure that you have an application installed which handles opening such link types."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"permission_service": {
|
||||||
|
"dialog": {
|
||||||
|
"title": "Storage permission",
|
||||||
|
"description": "Storage permission should be granted to the app so that it can work properly. Do you want to grant permission or ignore this message permanently in the future?",
|
||||||
|
"grant": "Grant",
|
||||||
|
"ignore": "Ignore"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dialog": {
|
"dialog": {
|
||||||
"confirm": "OK",
|
"confirm": "OK",
|
||||||
"cancel": "Cancel"
|
"cancel": "Cancel"
|
||||||
|
|
|
@ -1,100 +1,108 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io' show Platform;
|
|
||||||
|
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
import '../../constants.dart';
|
import '../../constants.dart';
|
||||||
|
import '../../core/datamodels/dialog_response.dart';
|
||||||
|
import '../../core/services/dialog_service.dart';
|
||||||
import '../../core/services/stoppable_service.dart';
|
import '../../core/services/stoppable_service.dart';
|
||||||
import '../../core/util/logger.dart';
|
import '../../core/util/logger.dart';
|
||||||
|
import '../../locator.dart';
|
||||||
|
import 'storage_service.dart';
|
||||||
|
|
||||||
class PermissionService extends StoppableService {
|
class PermissionService extends StoppableService {
|
||||||
final Logger _logger = getLogger();
|
final Logger _logger = getLogger();
|
||||||
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
final StorageService _storageService = locator<StorageService>();
|
||||||
|
|
||||||
Timer? _serviceCheckTimer;
|
Timer? _serviceCheckTimer;
|
||||||
|
|
||||||
|
PermissionStatus? _permissionStatus;
|
||||||
|
|
||||||
|
bool _permanentlyIgnored = false;
|
||||||
bool _devicePermissionDialogActive = false;
|
bool _devicePermissionDialogActive = false;
|
||||||
|
bool _ownPermissionDialogActive = false;
|
||||||
|
|
||||||
bool _deviceInformationInitialized = false;
|
PermissionService() {
|
||||||
bool _useStoragePermission = true;
|
_devicePermissionDialogActive = true;
|
||||||
|
|
||||||
PermissionService();
|
Permission.storage.request().then((status) {
|
||||||
|
_permissionStatus = status;
|
||||||
|
if (PermissionStatus.permanentlyDenied == status) {
|
||||||
|
_permanentlyIgnored = true;
|
||||||
|
}
|
||||||
|
}).whenComplete(() {
|
||||||
|
_logger.d('Initial device request permission finished');
|
||||||
|
_devicePermissionDialogActive = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future checkEnabledAndPermission() async {
|
Future checkEnabledAndPermission() async {
|
||||||
|
if (_permanentlyIgnored) {
|
||||||
|
await _storageService.storeStoragePermissionDialogIgnored();
|
||||||
|
_permanentlyIgnored = false;
|
||||||
|
_logger.d('Set permanently ignored permission request');
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
if (_devicePermissionDialogActive) {
|
if (_devicePermissionDialogActive) {
|
||||||
_logger.d('Device permission dialog active, skipping');
|
_logger.d('Device permission dialog active, skipping');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allGranted = false;
|
if (_ownPermissionDialogActive) {
|
||||||
bool anyPermanentlyDenied = false;
|
_logger.d('Own permission dialog already active, skipping');
|
||||||
|
return;
|
||||||
// Since Android compileSdk >= 33, "storage" is deprecated
|
|
||||||
// Instead, request access to all of
|
|
||||||
// - Permission.photos
|
|
||||||
// - Permission.videos
|
|
||||||
// - Permission.audio
|
|
||||||
//
|
|
||||||
// For iOS and Android < 33, keep using "storage"
|
|
||||||
if (_useStoragePermission) {
|
|
||||||
PermissionStatus storagePermission = await Permission.storage.status;
|
|
||||||
allGranted = PermissionStatus.granted == storagePermission;
|
|
||||||
anyPermanentlyDenied =
|
|
||||||
PermissionStatus.permanentlyDenied == storagePermission;
|
|
||||||
} else {
|
|
||||||
PermissionStatus photosPermission = await Permission.photos.status;
|
|
||||||
PermissionStatus videosPermission = await Permission.videos.status;
|
|
||||||
PermissionStatus audioPermission = await Permission.audio.status;
|
|
||||||
|
|
||||||
allGranted = PermissionStatus.granted == photosPermission &&
|
|
||||||
PermissionStatus.granted == videosPermission &&
|
|
||||||
PermissionStatus.granted == audioPermission;
|
|
||||||
anyPermanentlyDenied =
|
|
||||||
PermissionStatus.permanentlyDenied == photosPermission ||
|
|
||||||
PermissionStatus.permanentlyDenied == videosPermission ||
|
|
||||||
PermissionStatus.permanentlyDenied == audioPermission;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// show warning to user to manually handle, don't enforce it over and over again
|
var ignoredDialog =
|
||||||
if (anyPermanentlyDenied) {
|
await _storageService.hasStoragePermissionDialogIgnored();
|
||||||
_logger.w(
|
|
||||||
"At least one required permission has been denied permanently, stopping service");
|
if (ignoredDialog) {
|
||||||
|
_logger.d('Permanently ignored permission request, skipping');
|
||||||
stop();
|
stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all good, stop the permission service
|
_permissionStatus = await Permission.storage.status;
|
||||||
if (allGranted) {
|
if (_permissionStatus != PermissionStatus.granted) {
|
||||||
_logger.d("All permissions have been granted, stopping service");
|
if (_permissionStatus == PermissionStatus.permanentlyDenied) {
|
||||||
stop();
|
await _storageService.storeStoragePermissionDialogIgnored();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not all have been granted, show OS dialog
|
_ownPermissionDialogActive = true;
|
||||||
_logger.d(
|
DialogResponse response = await _dialogService.showConfirmationDialog(
|
||||||
"Not all permissions have been granted yet, initializing permission dialog");
|
title: translate('permission_service.dialog.title'),
|
||||||
_devicePermissionDialogActive = true;
|
description: translate('permission_service.dialog.description'),
|
||||||
|
buttonTitleAccept: translate('permission_service.dialog.grant'),
|
||||||
|
buttonTitleDeny: translate('permission_service.dialog.ignore'));
|
||||||
|
|
||||||
if (_useStoragePermission) {
|
if (!response.confirmed!) {
|
||||||
await [Permission.storage].request().whenComplete(() {
|
await _storageService.storeStoragePermissionDialogIgnored();
|
||||||
_logger.d('Device request permission finished');
|
} else {
|
||||||
_devicePermissionDialogActive = false;
|
_devicePermissionDialogActive = true;
|
||||||
});
|
Permission.storage.request().then((status) async {
|
||||||
|
if (PermissionStatus.permanentlyDenied == status) {
|
||||||
|
await _storageService.storeStoragePermissionDialogIgnored();
|
||||||
|
}
|
||||||
|
}).whenComplete(() {
|
||||||
|
_logger.d('Device request permission finished');
|
||||||
|
_devicePermissionDialogActive = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ownPermissionDialogActive = false;
|
||||||
} else {
|
} else {
|
||||||
await [Permission.photos, Permission.videos, Permission.audio]
|
await _storageService.storeStoragePermissionDialogIgnored();
|
||||||
.request()
|
|
||||||
.whenComplete(() {
|
|
||||||
_logger.d('Device request permission finished');
|
|
||||||
_devicePermissionDialogActive = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future start() async {
|
Future start() async {
|
||||||
super.start();
|
super.start();
|
||||||
await _determineDeviceInfo();
|
|
||||||
await checkEnabledAndPermission();
|
await checkEnabledAndPermission();
|
||||||
|
|
||||||
_serviceCheckTimer = Timer.periodic(
|
_serviceCheckTimer = Timer.periodic(
|
||||||
|
@ -116,29 +124,6 @@ class PermissionService extends StoppableService {
|
||||||
_logger.d('PermissionService stopped');
|
_logger.d('PermissionService stopped');
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _determineDeviceInfo() async {
|
|
||||||
if (_deviceInformationInitialized) {
|
|
||||||
_logger.d('Device information already initialized, skipping');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
|
|
||||||
if (Platform.isAndroid) {
|
|
||||||
final androidInfo = await deviceInfoPlugin.androidInfo;
|
|
||||||
if (androidInfo.version.sdkInt >= 33) {
|
|
||||||
_useStoragePermission = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_useStoragePermission) {
|
|
||||||
_logger.d('Device requires [storage] permission');
|
|
||||||
} else {
|
|
||||||
_logger.d('Device requires [photos,videos,audio] permission');
|
|
||||||
}
|
|
||||||
|
|
||||||
_deviceInformationInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _removeServiceCheckTimer() {
|
void _removeServiceCheckTimer() {
|
||||||
if (_serviceCheckTimer != null) {
|
if (_serviceCheckTimer != null) {
|
||||||
_serviceCheckTimer!.cancel();
|
_serviceCheckTimer!.cancel();
|
||||||
|
|
|
@ -7,6 +7,8 @@ import '../models/session.dart';
|
||||||
class StorageService {
|
class StorageService {
|
||||||
static const _sessionKey = 'session';
|
static const _sessionKey = 'session';
|
||||||
static const _lastUrlKey = 'last_url';
|
static const _lastUrlKey = 'last_url';
|
||||||
|
static const _storagePermissionDialogIgnoredKey =
|
||||||
|
'storage_permission_ignored';
|
||||||
|
|
||||||
Future<bool> storeLastUrl(String url) {
|
Future<bool> storeLastUrl(String url) {
|
||||||
return _store(_lastUrlKey, url);
|
return _store(_lastUrlKey, url);
|
||||||
|
@ -37,6 +39,14 @@ class StorageService {
|
||||||
return _remove(_sessionKey);
|
return _remove(_sessionKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> storeStoragePermissionDialogIgnored() {
|
||||||
|
return _store(_storagePermissionDialogIgnoredKey, true.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> hasStoragePermissionDialogIgnored() {
|
||||||
|
return _exists(_storagePermissionDialogIgnoredKey);
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> _exists(String key) async {
|
Future<bool> _exists(String key) async {
|
||||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
return prefs.containsKey(key);
|
return prefs.containsKey(key);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:fbmobile/core/services/permission_service.dart';
|
|
||||||
import 'package:flutter_translate/flutter_translate.dart';
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
import '../../locator.dart';
|
import '../../locator.dart';
|
||||||
|
@ -10,18 +9,16 @@ import 'base_model.dart';
|
||||||
|
|
||||||
class StartUpViewModel extends BaseModel {
|
class StartUpViewModel extends BaseModel {
|
||||||
final SessionService _sessionService = locator<SessionService>();
|
final SessionService _sessionService = locator<SessionService>();
|
||||||
final PermissionService _permissionService = locator<PermissionService>();
|
|
||||||
final NavigationService _navigationService = locator<NavigationService>();
|
final NavigationService _navigationService = locator<NavigationService>();
|
||||||
|
|
||||||
Future handleStartUpLogic() async {
|
Future handleStartUpLogic() async {
|
||||||
setStateView(ViewState.busy);
|
setStateView(ViewState.busy);
|
||||||
setStateMessage(translate('startup.init'));
|
setStateMessage(translate('startup.init'));
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 150));
|
||||||
|
|
||||||
setStateMessage(translate('startup.start_services'));
|
setStateMessage(translate('startup.start_services'));
|
||||||
await _sessionService.start();
|
await _sessionService.start();
|
||||||
await _permissionService.start();
|
await Future.delayed(const Duration(milliseconds: 150));
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
|
||||||
|
|
||||||
_navigationService.navigateAndReplaceTo(HomeView.routeName);
|
_navigationService.navigateAndReplaceTo(HomeView.routeName);
|
||||||
|
|
||||||
|
|
108
pubspec.lock
108
pubspec.lock
|
@ -61,18 +61,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
|
sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.1"
|
version: "4.0.0"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_resolvers
|
name: build_resolvers
|
||||||
sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8"
|
sha256: d912852cce27c9e80a93603db721c267716894462e7033165178b91138587972
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.1"
|
version: "2.3.2"
|
||||||
build_runner:
|
build_runner:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -85,10 +85,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185
|
sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.2.11"
|
version: "7.2.10"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -101,10 +101,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
sha256: "69acb7007eb2a31dc901512bfe0f7b767168be34cb734835d54c070bfa74c1b2"
|
sha256: a8de5955205b4d1dbbbc267daddf2178bd737e4bab8987c04a500478c9651e74
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.8.0"
|
version: "8.6.3"
|
||||||
built_value_generator:
|
built_value_generator:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -149,10 +149,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: code_builder
|
name: code_builder
|
||||||
sha256: b2151ce26a06171005b379ecff6e08d34c470180ffe16b8e14b6d52be292b55f
|
sha256: "315a598c7fbe77f22de1c9da7cfd6fd21816312f16ffa124453b4fc679e540f1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.8.0"
|
version: "4.6.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -173,10 +173,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cross_file
|
name: cross_file
|
||||||
sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5"
|
sha256: fd832b5384d0d6da4f6df60b854d33accaaeb63aa9e10e736a87381f08dee2cb
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.3+7"
|
version: "0.3.3+5"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -197,26 +197,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368"
|
sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.4"
|
version: "2.3.3"
|
||||||
device_info_plus:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: device_info_plus
|
|
||||||
sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "9.1.1"
|
|
||||||
device_info_plus_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: device_info_plus_platform_interface
|
|
||||||
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.0.0"
|
|
||||||
dynamic_color:
|
dynamic_color:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -253,10 +237,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
|
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.0"
|
version: "6.1.4"
|
||||||
file_picker:
|
file_picker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -303,10 +287,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_plugin_android_lifecycle
|
name: flutter_plugin_android_lifecycle
|
||||||
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
|
sha256: f185ac890306b5779ecbd611f52502d8d4d63d27703ef73161ca0407e815f02c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.17"
|
version: "2.0.16"
|
||||||
flutter_sharing_intent:
|
flutter_sharing_intent:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -545,10 +529,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
|
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.0"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -633,18 +617,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
|
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "3.1.2"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
|
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.7"
|
version: "2.1.6"
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -721,10 +705,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_linux
|
name: shared_preferences_linux
|
||||||
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
|
sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.3.1"
|
||||||
shared_preferences_platform_interface:
|
shared_preferences_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -737,18 +721,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_web
|
name: shared_preferences_web
|
||||||
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
|
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.2"
|
version: "2.2.1"
|
||||||
shared_preferences_windows:
|
shared_preferences_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_windows
|
name: shared_preferences_windows
|
||||||
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
|
sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.2"
|
version: "2.3.1"
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -794,14 +778,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0"
|
version: "1.10.0"
|
||||||
sprintf:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: sprintf
|
|
||||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "7.0.0"
|
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -910,10 +886,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_ios
|
name: url_launcher_ios
|
||||||
sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3
|
sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.1"
|
version: "6.2.0"
|
||||||
url_launcher_linux:
|
url_launcher_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -942,10 +918,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: url_launcher_web
|
name: url_launcher_web
|
||||||
sha256: "138bd45b3a456dcfafc46d1a146787424f8d2edfbf2809c9324361e58f851cf7"
|
sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.0"
|
||||||
url_launcher_windows:
|
url_launcher_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -958,10 +934,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: uuid
|
name: uuid
|
||||||
sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921
|
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.1"
|
version: "3.0.7"
|
||||||
validators:
|
validators:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -1006,18 +982,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f"
|
sha256: c97defd418eef4ec88c0d1652cdce84b9f7b63dd7198e266d06ac1710d527067
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.0"
|
version: "5.0.8"
|
||||||
win32_registry:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: win32_registry
|
|
||||||
sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.1.2"
|
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -14,7 +14,7 @@ description: A mobile client for FileBin.
|
||||||
version: 1.6.2+20
|
version: 1.6.2+20
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.2.0 <4.0.0'
|
sdk: '>=3.1.0 <4.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
@ -43,7 +43,6 @@ dependencies:
|
||||||
intl: 0.18.1
|
intl: 0.18.1
|
||||||
path: 1.8.3
|
path: 1.8.3
|
||||||
flutter_sharing_intent: 1.1.0
|
flutter_sharing_intent: 1.1.0
|
||||||
device_info_plus: 9.1.1
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in a new issue