upgraded flutter to v2.5.1
This commit is contained in:
parent
ea6f5d7df6
commit
e44e74d315
21 changed files with 167 additions and 106 deletions
2
.github/workflows/check.yml
vendored
2
.github/workflows/check.yml
vendored
|
@ -15,7 +15,7 @@ jobs:
|
|||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
channel: stable
|
||||
flutter-version: '2.5.0'
|
||||
flutter-version: '2.5.1'
|
||||
|
||||
- name: Clone the repository.
|
||||
uses: actions/checkout@v2
|
||||
|
|
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
- uses: subosito/flutter-action@v1
|
||||
with:
|
||||
channel: stable
|
||||
flutter-version: '2.5.0'
|
||||
flutter-version: '2.5.1'
|
||||
|
||||
# Workaround for this Android Gradle Plugin issue (supposedly fixed in AGP 4.1):
|
||||
# https://issuetracker.google.com/issues/144111441
|
||||
|
@ -50,8 +50,8 @@ jobs:
|
|||
echo "${{ secrets.KEY_JKS }}" > release.keystore.asc
|
||||
gpg -d --passphrase "${{ secrets.KEY_JKS_PASSPHRASE }}" --batch release.keystore.asc > $AVES_STORE_FILE
|
||||
rm release.keystore.asc
|
||||
flutter build apk --bundle-sksl-path shaders_2.5.0.sksl.json
|
||||
flutter build appbundle --bundle-sksl-path shaders_2.5.0.sksl.json
|
||||
flutter build apk --bundle-sksl-path shaders_2.5.1.sksl.json
|
||||
flutter build appbundle --bundle-sksl-path shaders_2.5.1.sksl.json
|
||||
rm $AVES_STORE_FILE
|
||||
env:
|
||||
AVES_STORE_FILE: ${{ github.workspace }}/key.jks
|
||||
|
|
|
@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
## [Unreleased]
|
||||
### Changed
|
||||
- upgraded Flutter to stable v2.5.0
|
||||
- upgraded Flutter to stable v2.5.1
|
||||
- faster collection loading when launching the app
|
||||
|
||||
## [v1.5.1] - 2021-09-08
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package deckers.thibault.aves.channel.calls
|
||||
|
||||
import android.app.Activity
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
||||
import deckers.thibault.aves.model.provider.MediaStoreImageProvider
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
|
@ -15,6 +17,7 @@ class MediaStoreHandler(private val activity: Activity) : MethodCallHandler {
|
|||
when (call.method) {
|
||||
"checkObsoleteContentIds" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::checkObsoleteContentIds) }
|
||||
"checkObsoletePaths" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::checkObsoletePaths) }
|
||||
"scanFile" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::scanFile) }
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +40,12 @@ class MediaStoreHandler(private val activity: Activity) : MethodCallHandler {
|
|||
result.success(MediaStoreImageProvider().checkObsoletePaths(activity, knownPathById))
|
||||
}
|
||||
|
||||
private fun scanFile(call: MethodCall, result: MethodChannel.Result) {
|
||||
val path = call.argument<String>("path")
|
||||
val mimeType = call.argument<String>("mimeType")
|
||||
MediaScannerConnection.scanFile(activity, arrayOf(path), arrayOf(mimeType)) { _, uri: Uri? -> result.success(uri?.toString()) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val CHANNEL = "deckers.thibault/aves/media_store"
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package deckers.thibault.aves.channel.calls
|
||||
|
||||
import android.content.Context
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.os.storage.StorageManager
|
||||
|
@ -30,7 +28,6 @@ class StorageHandler(private val context: Context) : MethodCallHandler {
|
|||
"getRestrictedDirectories" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::getRestrictedDirectories) }
|
||||
"revokeDirectoryAccess" -> safe(call, result, ::revokeDirectoryAccess)
|
||||
"deleteEmptyDirectories" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::deleteEmptyDirectories) }
|
||||
"scanFile" -> GlobalScope.launch(Dispatchers.IO) { safe(call, result, ::scanFile) }
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
@ -158,12 +155,6 @@ class StorageHandler(private val context: Context) : MethodCallHandler {
|
|||
result.success(deleted)
|
||||
}
|
||||
|
||||
private fun scanFile(call: MethodCall, result: MethodChannel.Result) {
|
||||
val path = call.argument<String>("path")
|
||||
val mimeType = call.argument<String>("mimeType")
|
||||
MediaScannerConnection.scanFile(context, arrayOf(path), arrayOf(mimeType)) { _, uri: Uri? -> result.success(uri?.toString()) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val CHANNEL = "deckers.thibault/aves/storage"
|
||||
}
|
||||
|
|
|
@ -64,9 +64,9 @@ object MimeTypes {
|
|||
else -> false
|
||||
}
|
||||
|
||||
// as of Flutter v1.22.0
|
||||
// as of Flutter v1.22.0, with additional custom handling for SVG
|
||||
fun canDecodeWithFlutter(mimeType: String, rotationDegrees: Int?, isFlipped: Boolean?) = when (mimeType) {
|
||||
JPEG, GIF, WEBP, BMP, WBMP, ICO -> true
|
||||
JPEG, GIF, WEBP, BMP, WBMP, ICO, SVG -> true
|
||||
PNG -> rotationDegrees ?: 0 == 0 && !(isFlipped ?: false)
|
||||
else -> false
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import 'package:aves/model/settings/screen_on.dart';
|
|||
import 'package:aves/model/source/enums.dart';
|
||||
import 'package:aves/services/common/services.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -111,13 +110,6 @@ class Settings extends ChangeNotifier {
|
|||
_isRotationLocked = await windowService.isRotationLocked();
|
||||
}
|
||||
|
||||
// Crashlytics initialization is separated from the main settings initialization
|
||||
// to allow settings customization without Firebase context (e.g. before a Flutter Driver test)
|
||||
Future<void> initFirebase() async {
|
||||
await Firebase.app().setAutomaticDataCollectionEnabled(isCrashlyticsEnabled);
|
||||
await reportService.setCollectionEnabled(isCrashlyticsEnabled);
|
||||
}
|
||||
|
||||
Future<void> reset({required bool includeInternalKeys}) async {
|
||||
if (includeInternalKeys) {
|
||||
await _prefs!.clear();
|
||||
|
@ -151,7 +143,7 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
set isCrashlyticsEnabled(bool newValue) {
|
||||
setAndNotify(isCrashlyticsEnabledKey, newValue);
|
||||
unawaited(initFirebase());
|
||||
unawaited(reportService.setCollectionEnabled(isCrashlyticsEnabled));
|
||||
}
|
||||
|
||||
static const localeSeparator = '-';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -27,7 +28,10 @@ class CrashlyticsReportService extends ReportService {
|
|||
bool get isCollectionEnabled => instance.isCrashlyticsCollectionEnabled;
|
||||
|
||||
@override
|
||||
Future<void> setCollectionEnabled(bool enabled) => instance.setCrashlyticsCollectionEnabled(enabled);
|
||||
Future<void> setCollectionEnabled(bool enabled) async {
|
||||
await Firebase.app().setAutomaticDataCollectionEnabled(enabled);
|
||||
await instance.setCrashlyticsCollectionEnabled(enabled);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> log(String message) => instance.log(message);
|
||||
|
|
|
@ -14,18 +14,18 @@ abstract class StorageService {
|
|||
|
||||
Future<List<String>> getGrantedDirectories();
|
||||
|
||||
Future<void> revokeDirectoryAccess(String path);
|
||||
|
||||
Future<Set<VolumeRelativeDirectory>> getInaccessibleDirectories(Iterable<String> dirPaths);
|
||||
|
||||
Future<Set<VolumeRelativeDirectory>> getRestrictedDirectories();
|
||||
|
||||
// returns whether user granted access to volume root at `volumePath`
|
||||
Future<bool> requestVolumeAccess(String volumePath);
|
||||
Future<void> revokeDirectoryAccess(String path);
|
||||
|
||||
// returns number of deleted directories
|
||||
Future<int> deleteEmptyDirectories(Iterable<String> dirPaths);
|
||||
|
||||
// returns whether user granted access to volume root at `volumePath`
|
||||
Future<bool> requestVolumeAccess(String volumePath);
|
||||
|
||||
// return whether operation succeeded (`null` if user cancelled)
|
||||
Future<bool?> createFile(String name, String mimeType, Uint8List bytes);
|
||||
|
||||
|
@ -73,18 +73,6 @@ class PlatformStorageService implements StorageService {
|
|||
return [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> revokeDirectoryAccess(String path) async {
|
||||
try {
|
||||
await platform.invokeMethod('revokeDirectoryAccess', <String, dynamic>{
|
||||
'path': path,
|
||||
});
|
||||
} on PlatformException catch (e, stack) {
|
||||
await reportService.recordError(e, stack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Set<VolumeRelativeDirectory>> getInaccessibleDirectories(Iterable<String> dirPaths) async {
|
||||
try {
|
||||
|
@ -113,6 +101,32 @@ class PlatformStorageService implements StorageService {
|
|||
return {};
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> revokeDirectoryAccess(String path) async {
|
||||
try {
|
||||
await platform.invokeMethod('revokeDirectoryAccess', <String, dynamic>{
|
||||
'path': path,
|
||||
});
|
||||
} on PlatformException catch (e, stack) {
|
||||
await reportService.recordError(e, stack);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// returns number of deleted directories
|
||||
@override
|
||||
Future<int> deleteEmptyDirectories(Iterable<String> dirPaths) async {
|
||||
try {
|
||||
final result = await platform.invokeMethod('deleteEmptyDirectories', <String, dynamic>{
|
||||
'dirPaths': dirPaths.toList(),
|
||||
});
|
||||
if (result != null) return result as int;
|
||||
} on PlatformException catch (e, stack) {
|
||||
await reportService.recordError(e, stack);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns whether user granted access to volume root at `volumePath`
|
||||
@override
|
||||
Future<bool> requestVolumeAccess(String volumePath) async {
|
||||
|
@ -136,20 +150,6 @@ class PlatformStorageService implements StorageService {
|
|||
return false;
|
||||
}
|
||||
|
||||
// returns number of deleted directories
|
||||
@override
|
||||
Future<int> deleteEmptyDirectories(Iterable<String> dirPaths) async {
|
||||
try {
|
||||
final result = await platform.invokeMethod('deleteEmptyDirectories', <String, dynamic>{
|
||||
'dirPaths': dirPaths.toList(),
|
||||
});
|
||||
if (result != null) return result as int;
|
||||
} on PlatformException catch (e, stack) {
|
||||
await reportService.recordError(e, stack);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool?> createFile(String name, String mimeType, Uint8List bytes) async {
|
||||
try {
|
||||
|
|
|
@ -139,7 +139,7 @@ class _AvesAppState extends State<AvesApp> {
|
|||
});
|
||||
});
|
||||
await settings.init();
|
||||
await settings.initFirebase();
|
||||
await reportService.setCollectionEnabled(settings.isCrashlyticsEnabled);
|
||||
_navigatorObservers = [
|
||||
CrashlyticsRouteTracker(),
|
||||
];
|
||||
|
|
|
@ -154,7 +154,7 @@ class _EntryLeafletMapState extends State<EntryLeafletMap> with TickerProviderSt
|
|||
minZoom: widget.minZoom,
|
||||
maxZoom: widget.maxZoom,
|
||||
interactiveFlags: interactive ? InteractiveFlag.all : InteractiveFlag.none,
|
||||
onTap: (point) => widget.onMapTap?.call(),
|
||||
onTap: (tapPosition, point) => widget.onMapTap?.call(),
|
||||
controller: _leafletMapController,
|
||||
),
|
||||
mapController: _leafletMapController,
|
||||
|
|
36
pubspec.lock
36
pubspec.lock
|
@ -7,14 +7,14 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "25.0.0"
|
||||
version: "26.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.3.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -28,7 +28,7 @@ packages:
|
|||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.3.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -378,7 +378,7 @@ packages:
|
|||
name: flutter_map
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.1"
|
||||
version: "0.14.0"
|
||||
flutter_markdown:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -456,7 +456,7 @@ packages:
|
|||
name: google_maps_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
version: "2.0.10"
|
||||
google_maps_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -498,7 +498,7 @@ packages:
|
|||
name: image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
version: "3.0.5"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -554,7 +554,7 @@ packages:
|
|||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
markdown:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -638,7 +638,7 @@ packages:
|
|||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.2"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -715,7 +715,7 @@ packages:
|
|||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.1.0"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -736,7 +736,7 @@ packages:
|
|||
name: pdf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.5.0"
|
||||
version: "3.6.0"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -757,7 +757,7 @@ packages:
|
|||
name: permission_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "8.1.4+2"
|
||||
version: "8.1.6"
|
||||
permission_handler_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -771,7 +771,7 @@ packages:
|
|||
name: petitparser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.2.0"
|
||||
version: "4.3.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -806,7 +806,7 @@ packages:
|
|||
name: printing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.5.0"
|
||||
version: "5.6.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -834,7 +834,7 @@ packages:
|
|||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
qr:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -855,7 +855,7 @@ packages:
|
|||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.7"
|
||||
version: "2.0.8"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1072,7 +1072,7 @@ packages:
|
|||
name: url_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.10"
|
||||
version: "6.0.11"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1184,7 +1184,7 @@ packages:
|
|||
name: xml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "5.3.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1194,4 +1194,4 @@ packages:
|
|||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.14.0 <3.0.0"
|
||||
flutter: ">=2.0.0"
|
||||
flutter: ">=2.5.0"
|
||||
|
|
|
@ -12,7 +12,7 @@ dependencies:
|
|||
sdk: flutter
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
# TODO TLAD as of 2021/09/09, the released version is incompatible with Flutter v2.5
|
||||
# TODO TLAD as of 2021/09/23, latest version (v0.11.0) is incompatible with Flutter v2.5
|
||||
charts_flutter:
|
||||
git:
|
||||
url: git://github.com/google/charts.git
|
||||
|
@ -20,7 +20,7 @@ dependencies:
|
|||
collection:
|
||||
connectivity_plus:
|
||||
country_code:
|
||||
# TODO TLAD as of 2021/08/04, null safe version is pre-release
|
||||
# TODO TLAD as of 2021/09/23, null safe version is pre-release
|
||||
custom_rounded_rectangle_border: '>=0.2.0-nullsafety.0'
|
||||
decorated_icon:
|
||||
device_info_plus:
|
||||
|
@ -47,12 +47,12 @@ dependencies:
|
|||
google_maps_flutter:
|
||||
intl:
|
||||
latlong2:
|
||||
# TODO TLAD as of 2021/08/04, null safe version is pre-release
|
||||
# TODO TLAD as of 2021/09/23, null safe version is pre-release
|
||||
material_design_icons_flutter: '>=5.0.5955-rc.1'
|
||||
overlay_support:
|
||||
package_info_plus:
|
||||
palette_generator:
|
||||
# TODO TLAD upgrade panorama when this is fixed: https://github.com/zesage/panorama/issues/25 (bug in v0.4.1)
|
||||
# TODO TLAD as of 2021/09/23, latest version (v0.4.1) has this issue: https://github.com/zesage/panorama/issues/25
|
||||
panorama: 0.4.0
|
||||
pdf:
|
||||
percent_indicator:
|
||||
|
|
1
shaders.sksl.json
Normal file
1
shaders.sksl.json
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
shaders_2.5.1.sksl.json
Normal file
1
shaders_2.5.1.sksl.json
Normal file
File diff suppressed because one or more lines are too long
26
test/fake/report_service.dart
Normal file
26
test/fake/report_service.dart
Normal file
|
@ -0,0 +1,26 @@
|
|||
import 'package:aves/services/report_service.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class FakeReportService extends ReportService {
|
||||
@override
|
||||
bool get isCollectionEnabled => false;
|
||||
|
||||
@override
|
||||
Future<void> setCollectionEnabled(bool enabled) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> log(String message) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> setCustomKey(String key, Object value) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> setCustomKeys(Map<String, Object> map) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> recordError(exception, StackTrace? stack) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails) => SynchronousFuture(null);
|
||||
}
|
|
@ -1,8 +1,21 @@
|
|||
import 'package:aves/services/window_service.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
class FakeWindowService extends Fake implements WindowService {
|
||||
@override
|
||||
Future<void> keepScreenOn(bool on) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<bool> isRotationLocked() => SynchronousFuture(false);
|
||||
|
||||
@override
|
||||
Future<void> requestOrientation([Orientation? orientation]) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<bool> canSetCutoutMode() => SynchronousFuture(true);
|
||||
|
||||
@override
|
||||
Future<void> setCutoutMode(bool use) => SynchronousFuture(null);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:aves/services/device_service.dart';
|
|||
import 'package:aves/services/media/media_file_service.dart';
|
||||
import 'package:aves/services/media/media_store_service.dart';
|
||||
import 'package:aves/services/metadata/metadata_fetch_service.dart';
|
||||
import 'package:aves/services/report_service.dart';
|
||||
import 'package:aves/services/storage_service.dart';
|
||||
import 'package:aves/services/window_service.dart';
|
||||
import 'package:aves/utils/android_file_utils.dart';
|
||||
|
@ -26,6 +27,7 @@ import '../fake/media_file_service.dart';
|
|||
import '../fake/media_store_service.dart';
|
||||
import '../fake/metadata_db.dart';
|
||||
import '../fake/metadata_fetch_service.dart';
|
||||
import '../fake/report_service.dart';
|
||||
import '../fake/storage_service.dart';
|
||||
import '../fake/window_service.dart';
|
||||
|
||||
|
@ -44,6 +46,7 @@ void main() {
|
|||
getIt.registerLazySingleton<MediaFileService>(() => FakeMediaFileService());
|
||||
getIt.registerLazySingleton<MediaStoreService>(() => FakeMediaStoreService());
|
||||
getIt.registerLazySingleton<MetadataFetchService>(() => FakeMetadataFetchService());
|
||||
getIt.registerLazySingleton<ReportService>(() => FakeReportService());
|
||||
getIt.registerLazySingleton<StorageService>(() => FakeStorageService());
|
||||
getIt.registerLazySingleton<WindowService>(() => FakeWindowService());
|
||||
|
||||
|
|
|
@ -5,10 +5,11 @@ import 'package:aves/model/settings/enums.dart';
|
|||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/services/common/services.dart';
|
||||
import 'package:aves/services/media/media_store_service.dart';
|
||||
import 'package:aves/services/report_service.dart';
|
||||
import 'package:aves/services/window_service.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/src/widgets/media_query.dart';
|
||||
import 'package:flutter_driver/driver_extension.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'constants.dart';
|
||||
|
@ -19,45 +20,65 @@ void main() {
|
|||
// scan files copied from test assets
|
||||
// we do it via the app instead of broadcasting via ADB
|
||||
// because `MEDIA_SCANNER_SCAN_FILE` intent got deprecated in API 29
|
||||
final mediaStoreService = PlatformMediaStoreService();
|
||||
mediaStoreService.scanFile(p.join(targetPicturesDir, 'aves_logo.svg'), 'image/svg+xml');
|
||||
mediaStoreService.scanFile(p.join(targetPicturesDir, 'ipse.jpg'), 'image/jpeg');
|
||||
PlatformMediaStoreService()
|
||||
..scanFile(p.join(targetPicturesDir, 'aves_logo.svg'), 'image/svg+xml')
|
||||
..scanFile(p.join(targetPicturesDir, 'ipse.jpg'), 'image/jpeg');
|
||||
|
||||
// something like `configure().then((_) => app.main());` does not behave as expected
|
||||
// and starts the app without waiting for `configure` to complete
|
||||
configureAndLaunch();
|
||||
}
|
||||
|
||||
Future<void> configureAndLaunch() async {
|
||||
// TODO TLAD [test] decouple services from settings setters, so there is no need for fake services here
|
||||
// set up fake services called during settings initialization
|
||||
final fakeWindowService = FakeWindowService();
|
||||
getIt.registerSingleton<WindowService>(fakeWindowService);
|
||||
getIt
|
||||
..registerSingleton<WindowService>(DriverInitWindowService())
|
||||
..registerSingleton<ReportService>(DriverInitReportService());
|
||||
|
||||
await settings.init();
|
||||
settings.keepScreenOn = KeepScreenOn.always;
|
||||
settings.hasAcceptedTerms = false;
|
||||
settings.isCrashlyticsEnabled = false;
|
||||
settings.locale = const Locale('en');
|
||||
settings.homePage = HomePageSetting.collection;
|
||||
settings.imageBackground = EntryBackground.checkered;
|
||||
settings
|
||||
..keepScreenOn = KeepScreenOn.always
|
||||
..hasAcceptedTerms = false
|
||||
..isCrashlyticsEnabled = false
|
||||
..locale = const Locale('en')
|
||||
..homePage = HomePageSetting.collection
|
||||
..imageBackground = EntryBackground.checkered;
|
||||
|
||||
// tear down fake services
|
||||
getIt.unregister<WindowService>(instance: fakeWindowService);
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
await getIt.reset();
|
||||
|
||||
app.main();
|
||||
}
|
||||
|
||||
class FakeWindowService implements WindowService {
|
||||
class DriverInitWindowService extends Fake implements WindowService {
|
||||
@override
|
||||
Future<void> keepScreenOn(bool on) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<bool> isRotationLocked() => SynchronousFuture(false);
|
||||
|
||||
@override
|
||||
Future<void> requestOrientation([Orientation? orientation]) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<bool> canSetCutoutMode() => SynchronousFuture(false);
|
||||
|
||||
@override
|
||||
Future<void> setCutoutMode(bool use) => SynchronousFuture(null);
|
||||
}
|
||||
|
||||
class DriverInitReportService extends Fake implements ReportService {
|
||||
@override
|
||||
bool get isCollectionEnabled => false;
|
||||
|
||||
@override
|
||||
Future<void> setCollectionEnabled(bool enabled) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> log(String message) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> setCustomKey(String key, Object value) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> setCustomKeys(Map<String, Object> map) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> recordError(exception, StackTrace? stack) => SynchronousFuture(null);
|
||||
|
||||
@override
|
||||
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails) => SynchronousFuture(null);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ late FlutterDriver driver;
|
|||
|
||||
void main() {
|
||||
group('[Aves app]', () {
|
||||
print('adb=${[adb, ...adbDeviceParam].join(' ')}');
|
||||
|
||||
setUpAll(() async {
|
||||
await copyContent(sourcePicturesDir, targetPicturesDir);
|
||||
await grantPermissions('deckers.thibault.aves.debug', [
|
||||
|
@ -53,6 +51,9 @@ void main() {
|
|||
|
||||
void agreeToTerms() {
|
||||
test('[welcome] agree to terms', () async {
|
||||
// delay to avoid flaky failures when widget binding is not ready from the start
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
|
||||
await driver.scroll(find.text('Terms of Service'), 0, -300, const Duration(milliseconds: 500));
|
||||
|
||||
await driver.tap(find.byValueKey('agree-checkbox'));
|
||||
|
|
Loading…
Reference in a new issue