#29 play/izzy flavors

This commit is contained in:
Thibault Deckers 2021-10-26 16:50:13 +09:00
parent e49f344e06
commit 4adaf73c73
44 changed files with 910 additions and 167 deletions

View file

@ -50,9 +50,15 @@ jobs:
echo "${{ secrets.KEY_JKS }}" > release.keystore.asc echo "${{ secrets.KEY_JKS }}" > release.keystore.asc
gpg -d --passphrase "${{ secrets.KEY_JKS_PASSPHRASE }}" --batch release.keystore.asc > $AVES_STORE_FILE gpg -d --passphrase "${{ secrets.KEY_JKS_PASSPHRASE }}" --batch release.keystore.asc > $AVES_STORE_FILE
rm release.keystore.asc rm release.keystore.asc
flutter build appbundle --flavor universal --bundle-sksl-path shaders_2.5.3.sksl.json mkdir outputs
flutter build apk --flavor universal --bundle-sksl-path shaders_2.5.3.sksl.json (cd scripts/; ./apply_flavor_play.sh)
flutter build apk --flavor byAbi --split-per-abi --bundle-sksl-path shaders_2.5.3.sksl.json flutter build appbundle -t lib/main_play.dart --flavor play --bundle-sksl-path shaders_2.5.3.sksl.json
cp build/app/outputs/bundle/playRelease/*.aab outputs
flutter build apk -t lib/main_play.dart --flavor play --bundle-sksl-path shaders_2.5.3.sksl.json
cp build/app/outputs/apk/play/release/*.apk outputs
(cd scripts/; ./apply_flavor_izzy.sh)
flutter build apk -t lib/main_izzy.dart --flavor izzy --split-per-abi --bundle-sksl-path shaders_2.5.3.sksl.json
cp build/app/outputs/apk/izzy/release/*.apk outputs
rm $AVES_STORE_FILE rm $AVES_STORE_FILE
env: env:
AVES_STORE_FILE: ${{ github.workspace }}/key.jks AVES_STORE_FILE: ${{ github.workspace }}/key.jks
@ -64,14 +70,14 @@ jobs:
- name: Create a release with the APK and App Bundle. - name: Create a release with the APK and App Bundle.
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
artifacts: "build/app/outputs/bundle/universalRelease/*.aab,build/app/outputs/apk/universal/release/*.apk,build/app/outputs/apk/byAbi/release/*.apk" artifacts: "outputs/*"
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload app bundle - name: Upload app bundle
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: appbundle name: appbundle
path: build/app/outputs/bundle/universalRelease/app-universal-release.aab path: outputs/app-play-release.aab
release: release:
name: Create beta release on Play Store. name: Create beta release on Play Store.
@ -90,7 +96,7 @@ jobs:
with: with:
serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_ACCOUNT_KEY }} serviceAccountJsonPlainText: ${{ secrets.PLAYSTORE_ACCOUNT_KEY }}
packageName: deckers.thibault.aves packageName: deckers.thibault.aves
releaseFiles: app-universal-release.aab releaseFiles: app-play-release.aab
track: beta track: beta
status: completed status: completed
whatsNewDirectory: whatsnew whatsNewDirectory: whatsnew

View file

@ -50,13 +50,22 @@ At this stage this project does *not* accept PRs, except for translations.
If you want to translate this app in your language and share the result, feel free to open a PR or send the translation by [email](mailto:gallery.aves@gmail.com). You can find some localization notes in [pubspec.yaml](https://github.com/deckerst/aves/blob/develop/pubspec.yaml). English, Korean and French (soon™) are already handled. If you want to translate this app in your language and share the result, feel free to open a PR or send the translation by [email](mailto:gallery.aves@gmail.com). You can find some localization notes in [pubspec.yaml](https://github.com/deckerst/aves/blob/develop/pubspec.yaml). English, Korean and French (soon™) are already handled.
### Donations ### Donations
Some users have expressed the wish to financially support the project. I haven't set up any sponsorship system, but you can send contributions [here](https://paypal.me/ThibaultDeckers). Thanks! ❤️ Some users have expressed the wish to financially support the project. I haven't set up any sponsorship system, but you can send contributions [here](https://paypal.me/ThibaultDeckers). Thanks! ❤️
## Project Setup ## Project Setup
Before running or building the app, update the dependencies for the desired flavor:
```
# (cd scripts/; ./apply_flavor_play.sh)
```
To build the project, create a file named `<app dir>/android/key.properties`. It should contain a reference to a keystore for app signing, and other necessary credentials. See [key_template.properties](https://github.com/deckerst/aves/blob/develop/android/key_template.properties) for the expected keys. To build the project, create a file named `<app dir>/android/key.properties`. It should contain a reference to a keystore for app signing, and other necessary credentials. See [key_template.properties](https://github.com/deckerst/aves/blob/develop/android/key_template.properties) for the expected keys.
You can run the app with `flutter run --flavor universal`. To run the app:
```
# flutter run -t lib/main_play.dart --flavor play
```
[Version badge]: https://img.shields.io/github/v/release/deckerst/aves?include_prereleases&sort=semver [Version badge]: https://img.shields.io/github/v/release/deckerst/aves?include_prereleases&sort=semver
[Build badge]: https://img.shields.io/github/workflow/status/deckerst/aves/Quality%20check [Build badge]: https://img.shields.io/github/workflow/status/deckerst/aves/Quality%20check

View file

@ -2,8 +2,6 @@ plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'kotlin-android'
id 'kotlin-kapt' id 'kotlin-kapt'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
} }
def appId = "deckers.thibault.aves" def appId = "deckers.thibault.aves"
@ -77,18 +75,25 @@ android {
} }
} }
// the "splitting" dimension and its flavors are only for building purposes: flavorDimensions "store"
// NDK ABI filters are not compatible with split APK generation
// but we want to generate both a universal APK without x86 libs, and split APKs
flavorDimensions "splitting"
productFlavors { productFlavors {
universal { play {
dimension "splitting" // Google Play
dimension "store"
ext.useCrashlytics = true
// generate a universal APK without x86 native libs
ext.useNdkAbiFilters = true
} }
byAbi { izzy {
dimension "splitting" // IzzyOnDroid
// check offending libraries with `scanapk`
// cf https://android.izzysoft.de/articles/named/app-modules-2
dimension "store"
ext.useCrashlytics = false
// generate APK by ABI, but NDK ABI filters are incompatible with split APK generation
ext.useNdkAbiFilters = false
} }
} }
@ -108,14 +113,16 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
} }
def runTasks = gradle.startParameter.taskNames.toString().toLowerCase() android.productFlavors.each { flavor ->
if (runTasks.contains("universal")) { def tasks = gradle.startParameter.taskNames.toString().toLowerCase()
release { if (tasks.contains(flavor.name) && flavor.ext.useNdkAbiFilters) {
// specify architectures, to specifically exclude native libs for x86, release {
// which lead to: UnsatisfiedLinkError...couldn't find "libflutter.so" // specify architectures, to specifically exclude native libs for x86,
// cf https://github.com/flutter/flutter/issues/37566#issuecomment-640879500 // which lead to: UnsatisfiedLinkError...couldn't find "libflutter.so"
ndk { // cf https://github.com/flutter/flutter/issues/37566#issuecomment-640879500
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64' ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
}
} }
} }
} }
@ -132,7 +139,7 @@ repositories {
} }
dependencies { dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
implementation 'androidx.core:core-ktx:1.6.0' implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.exifinterface:exifinterface:1.3.3' implementation 'androidx.exifinterface:exifinterface:1.3.3'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
@ -150,3 +157,12 @@ dependencies {
compileOnly rootProject.findProject(':streams_channel') compileOnly rootProject.findProject(':streams_channel')
} }
android.productFlavors.each { flavor ->
def tasks = gradle.startParameter.taskRequests.toString().toLowerCase()
if (tasks.contains(flavor.name) && flavor.ext.useCrashlytics) {
println("Building flavor with Crashlytics [${flavor.name}] - applying plugin")
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
}
}

View file

@ -6,8 +6,9 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.2' classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// GMS & Firebase Crashlytics are not actually used by all flavors
classpath 'com.google.gms:google-services:4.3.10' classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
} }

View file

@ -9,7 +9,7 @@ This app is released “as-is”, without any warranty, responsibility or liabil
# Privacy policy # Privacy policy
Aves does not collect any personal data in its standard use. We never have access to your photos and videos. This also means that we cannot get them back for you if you delete them without backing them up. Aves does not collect any personal data in its standard use. We never have access to your photos and videos. This also means that we cannot get them back for you if you delete them without backing them up.
__We collect anonymous data to improve the app.__ We use Google Firebase for Crash Reporting, and the anonymous data are stored on their servers. Please note that those are anonymous data, there is absolutely nothing personal about those data. In the “Play” edition of Aves, __anonymous data is collected to improve the app.__ We use Firebase Crashlytics, and the anonymous data are stored on their servers. Please note that those are anonymous data, there is absolutely nothing personal about those data.
## Links ## Links
[Sources](https://github.com/deckerst/aves) [Sources](https://github.com/deckerst/aves)

5
lib/app_flavor.dart Normal file
View file

@ -0,0 +1,5 @@
enum AppFlavor { play, izzy }
extension ExtraAppFlavor on AppFlavor {
bool get canEnableErrorReporting => this == AppFlavor.play;
}

View file

@ -1,10 +1,11 @@
import 'dart:isolate'; import 'dart:isolate';
import 'package:aves/app_flavor.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/aves_app.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
void main() { void mainCommon(AppFlavor flavor) {
// HttpClient.enableTimelineLogging = true; // enable network traffic logging // HttpClient.enableTimelineLogging = true; // enable network traffic logging
// debugPrintGestureArenaDiagnostics = true; // debugPrintGestureArenaDiagnostics = true;
@ -27,5 +28,5 @@ void main() {
reportService.recordError(errorAndStacktrace.first, errorAndStacktrace.last); reportService.recordError(errorAndStacktrace.first, errorAndStacktrace.last);
}).sendPort); }).sendPort);
runApp(const AvesApp()); runApp(AvesApp(flavor: flavor));
} }

6
lib/main_izzy.dart Normal file
View file

@ -0,0 +1,6 @@
import 'package:aves/app_flavor.dart';
import 'package:aves/main_common.dart';
void main() {
mainCommon(AppFlavor.izzy);
}

6
lib/main_play.dart Normal file
View file

@ -0,0 +1,6 @@
import 'package:aves/app_flavor.dart';
import 'package:aves/main_common.dart';
void main() {
mainCommon(AppFlavor.play);
}

View file

@ -7,9 +7,10 @@ import 'package:aves/services/media/media_file_service.dart';
import 'package:aves/services/media/media_store_service.dart'; import 'package:aves/services/media/media_store_service.dart';
import 'package:aves/services/metadata/metadata_edit_service.dart'; import 'package:aves/services/metadata/metadata_edit_service.dart';
import 'package:aves/services/metadata/metadata_fetch_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/storage_service.dart';
import 'package:aves/services/window_service.dart'; import 'package:aves/services/window_service.dart';
import 'package:aves_report/aves_report.dart';
import 'package:aves_report_platform/aves_report_platform.dart';
import 'package:get_it/get_it.dart'; import 'package:get_it/get_it.dart';
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
@ -42,7 +43,7 @@ void initPlatformServices() {
getIt.registerLazySingleton<MediaStoreService>(() => PlatformMediaStoreService()); getIt.registerLazySingleton<MediaStoreService>(() => PlatformMediaStoreService());
getIt.registerLazySingleton<MetadataEditService>(() => PlatformMetadataEditService()); getIt.registerLazySingleton<MetadataEditService>(() => PlatformMetadataEditService());
getIt.registerLazySingleton<MetadataFetchService>(() => PlatformMetadataFetchService()); getIt.registerLazySingleton<MetadataFetchService>(() => PlatformMetadataFetchService());
getIt.registerLazySingleton<ReportService>(() => CrashlyticsReportService()); getIt.registerLazySingleton<ReportService>(() => PlatformReportService());
getIt.registerLazySingleton<StorageService>(() => PlatformStorageService()); getIt.registerLazySingleton<StorageService>(() => PlatformStorageService());
getIt.registerLazySingleton<WindowService>(() => PlatformWindowService()); getIt.registerLazySingleton<WindowService>(() => PlatformWindowService());
} }

View file

@ -1,5 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:aves/app_flavor.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';
@ -86,7 +87,7 @@ class Constants {
), ),
]; ];
static const List<Dependency> flutterPlugins = [ static const List<Dependency> _flutterPluginsCommon = [
Dependency( Dependency(
name: 'Connectivity Plus', name: 'Connectivity Plus',
license: 'BSD 3-Clause', license: 'BSD 3-Clause',
@ -99,11 +100,6 @@ class Constants {
licenseUrl: 'https://github.com/fluttercommunity/plus_plugins/blob/main/packages/device_info_plus/device_info_plus/LICENSE', licenseUrl: 'https://github.com/fluttercommunity/plus_plugins/blob/main/packages/device_info_plus/device_info_plus/LICENSE',
sourceUrl: 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/device_info_plus', sourceUrl: 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/device_info_plus',
), ),
Dependency(
name: 'FlutterFire (Core, Crashlytics)',
license: 'BSD 3-Clause',
sourceUrl: 'https://github.com/FirebaseExtended/flutterfire',
),
Dependency( Dependency(
name: 'fijkplayer (Aves fork)', name: 'fijkplayer (Aves fork)',
license: 'MIT', license: 'MIT',
@ -160,6 +156,19 @@ class Constants {
), ),
]; ];
static const List<Dependency> _flutterPluginsPlayOnly = [
Dependency(
name: 'FlutterFire (Core, Crashlytics)',
license: 'BSD 3-Clause',
sourceUrl: 'https://github.com/FirebaseExtended/flutterfire',
),
];
static List<Dependency> flutterPlugins(AppFlavor flavor) => [
..._flutterPluginsCommon,
if (flavor == AppFlavor.play) ..._flutterPluginsPlayOnly,
];
static const List<Dependency> flutterPackages = [ static const List<Dependency> flutterPackages = [
Dependency( Dependency(
name: 'Charts', name: 'Charts',

View file

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:aves/app_flavor.dart';
import 'package:aves/flutter_version.dart'; import 'package:aves/flutter_version.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
@ -33,7 +34,7 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_infoLoader = _getInfo(); _infoLoader = _getInfo(context);
} }
@override @override
@ -123,12 +124,13 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
); );
} }
Future<String> _getInfo() async { Future<String> _getInfo(BuildContext context) async {
final packageInfo = await PackageInfo.fromPlatform(); final packageInfo = await PackageInfo.fromPlatform();
final androidInfo = await DeviceInfoPlugin().androidInfo; final androidInfo = await DeviceInfoPlugin().androidInfo;
final hasPlayServices = await availability.hasPlayServices; final hasPlayServices = await availability.hasPlayServices;
final flavor = context.read<AppFlavor>().toString().split('.')[1];
return [ return [
'Aves version: ${packageInfo.version} (Build ${packageInfo.buildNumber})', 'Aves version: ${packageInfo.version}-$flavor (Build ${packageInfo.buildNumber})',
'Flutter version: ${version['frameworkVersion']} (Channel ${version['channel']})', 'Flutter version: ${version['frameworkVersion']} (Channel ${version['channel']})',
'Android version: ${androidInfo.version.release} (SDK ${androidInfo.version.sdkInt})', 'Android version: ${androidInfo.version.release} (SDK ${androidInfo.version.sdkInt})',
'Device: ${androidInfo.manufacturer} ${androidInfo.model}', 'Device: ${androidInfo.manufacturer} ${androidInfo.model}',

View file

@ -1,3 +1,4 @@
import 'package:aves/app_flavor.dart';
import 'package:aves/ref/brand_colors.dart'; import 'package:aves/ref/brand_colors.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/link_chip.dart'; import 'package:aves/widgets/common/basic/link_chip.dart';
@ -6,6 +7,7 @@ import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/common/identity/buttons.dart'; import 'package:aves/widgets/common/identity/buttons.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Licenses extends StatefulWidget { class Licenses extends StatefulWidget {
const Licenses({Key? key}) : super(key: key); const Licenses({Key? key}) : super(key: key);
@ -22,7 +24,7 @@ class _LicensesState extends State<Licenses> {
void initState() { void initState() {
super.initState(); super.initState();
_platform = List<Dependency>.from(Constants.androidDependencies); _platform = List<Dependency>.from(Constants.androidDependencies);
_flutterPlugins = List<Dependency>.from(Constants.flutterPlugins); _flutterPlugins = List<Dependency>.from(Constants.flutterPlugins(context.read<AppFlavor>()));
_flutterPackages = List<Dependency>.from(Constants.flutterPackages); _flutterPackages = List<Dependency>.from(Constants.flutterPackages);
_dartPackages = List<Dependency>.from(Constants.dartPackages); _dartPackages = List<Dependency>.from(Constants.dartPackages);
_sortPackages(); _sortPackages();

View file

@ -1,5 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:aves/app_flavor.dart';
import 'package:aves/app_mode.dart'; import 'package:aves/app_mode.dart';
import 'package:aves/model/settings/accessibility_animations.dart'; import 'package:aves/model/settings/accessibility_animations.dart';
import 'package:aves/model/settings/screen_on.dart'; import 'package:aves/model/settings/screen_on.dart';
@ -29,7 +30,12 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class AvesApp extends StatefulWidget { class AvesApp extends StatefulWidget {
const AvesApp({Key? key}) : super(key: key); final AppFlavor flavor;
const AvesApp({
Key? key,
required this.flavor,
}) : super(key: key);
@override @override
_AvesAppState createState() => _AvesAppState(); _AvesAppState createState() => _AvesAppState();
@ -68,59 +74,62 @@ class _AvesAppState extends State<AvesApp> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
// place the settings provider above `MaterialApp` // place the settings provider above `MaterialApp`
// so it can be used during navigation transitions // so it can be used during navigation transitions
return ChangeNotifierProvider<Settings>.value( return Provider<AppFlavor>.value(
value: settings, value: widget.flavor,
child: ListenableProvider<ValueNotifier<AppMode>>.value( child: ChangeNotifierProvider<Settings>.value(
value: appModeNotifier, value: settings,
child: Provider<CollectionSource>.value( child: ListenableProvider<ValueNotifier<AppMode>>.value(
value: _mediaStoreSource, value: appModeNotifier,
child: DurationsProvider( child: Provider<CollectionSource>.value(
child: HighlightInfoProvider( value: _mediaStoreSource,
child: OverlaySupport( child: DurationsProvider(
child: FutureBuilder<void>( child: HighlightInfoProvider(
future: _appSetup, child: OverlaySupport(
builder: (context, snapshot) { child: FutureBuilder<void>(
final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done; future: _appSetup,
final home = initialized builder: (context, snapshot) {
? getFirstPage() final initialized = !snapshot.hasError && snapshot.connectionState == ConnectionState.done;
: Scaffold( final home = initialized
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(), ? getFirstPage()
: Scaffold(
body: snapshot.hasError ? _buildError(snapshot.error!) : const SizedBox(),
);
return Selector<Settings, Tuple2<Locale?, bool>>(
selector: (context, s) => Tuple2(s.locale, s.initialized ? s.accessibilityAnimations.animate : true),
builder: (context, s, child) {
final settingsLocale = s.item1;
final areAnimationsEnabled = s.item2;
return MaterialApp(
navigatorKey: _navigatorKey,
home: home,
navigatorObservers: _navigatorObservers,
builder: (context, child) {
if (!areAnimationsEnabled) {
child = Theme(
data: Theme.of(context).copyWith(
// strip page transitions used by `MaterialPageRoute`
pageTransitionsTheme: DirectPageTransitionsTheme(),
),
child: child!,
);
}
return child!;
},
onGenerateTitle: (context) => context.l10n.appName,
darkTheme: Themes.darkTheme,
themeMode: ThemeMode.dark,
locale: settingsLocale,
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
],
supportedLocales: AppLocalizations.supportedLocales,
// checkerboardRasterCacheImages: true,
// checkerboardOffscreenLayers: true,
); );
return Selector<Settings, Tuple2<Locale?, bool>>( },
selector: (context, s) => Tuple2(s.locale, s.initialized ? s.accessibilityAnimations.animate : true), );
builder: (context, s, child) { },
final settingsLocale = s.item1; ),
final areAnimationsEnabled = s.item2;
return MaterialApp(
navigatorKey: _navigatorKey,
home: home,
navigatorObservers: _navigatorObservers,
builder: (context, child) {
if (!areAnimationsEnabled) {
child = Theme(
data: Theme.of(context).copyWith(
// strip page transitions used by `MaterialPageRoute`
pageTransitionsTheme: DirectPageTransitionsTheme(),
),
child: child!,
);
}
return child!;
},
onGenerateTitle: (context) => context.l10n.appName,
darkTheme: Themes.darkTheme,
themeMode: ThemeMode.dark,
locale: settingsLocale,
localizationsDelegates: const [
...AppLocalizations.localizationsDelegates,
],
supportedLocales: AppLocalizations.supportedLocales,
// checkerboardRasterCacheImages: true,
// checkerboardOffscreenLayers: true,
);
},
);
},
), ),
), ),
), ),

View file

@ -50,7 +50,7 @@ class _AppDebugPageState extends State<AppDebugPage> {
const DebugAndroidEnvironmentSection(), const DebugAndroidEnvironmentSection(),
const DebugCacheSection(), const DebugCacheSection(),
const DebugAppDatabaseSection(), const DebugAppDatabaseSection(),
const DebugFirebaseSection(), const DebugErrorReportingSection(),
const DebugSettingsSection(), const DebugSettingsSection(),
const DebugStorageSection(), const DebugStorageSection(),
], ],

View file

@ -2,11 +2,10 @@ import 'package:aves/services/android_debug_service.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/widgets/common/identity/aves_expansion_tile.dart'; import 'package:aves/widgets/common/identity/aves_expansion_tile.dart';
import 'package:aves/widgets/viewer/info/common.dart'; import 'package:aves/widgets/viewer/info/common.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DebugFirebaseSection extends StatelessWidget { class DebugErrorReportingSection extends StatelessWidget {
const DebugFirebaseSection({Key? key}) : super(key: key); const DebugErrorReportingSection({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -51,10 +50,7 @@ class DebugFirebaseSection extends StatelessWidget {
Padding( Padding(
padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8), padding: const EdgeInsets.only(left: 8, right: 8, bottom: 8),
child: InfoRowGroup( child: InfoRowGroup(
info: { info: reportService.state,
'Firebase data collection enabled': '${Firebase.app().isAutomaticDataCollectionEnabled}',
'Crashlytics collection enabled': '${reportService.isCollectionEnabled}',
},
), ),
) )
], ],

View file

@ -1,3 +1,4 @@
import 'package:aves/app_flavor.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/color_utils.dart'; import 'package:aves/utils/color_utils.dart';
@ -20,8 +21,7 @@ class PrivacySection extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final currentIsErrorReportingEnabled = context.select<Settings, bool>((s) => s.isErrorReportingEnabled); final canEnableErrorReporting = context.select<AppFlavor, bool>((v) => v.canEnableErrorReporting);
final currentSaveSearchHistory = context.select<Settings, bool>((s) => s.saveSearchHistory);
return AvesExpansionTile( return AvesExpansionTile(
leading: SettingsTileLeading( leading: SettingsTileLeading(
@ -32,20 +32,27 @@ class PrivacySection extends StatelessWidget {
expandedNotifier: expandedNotifier, expandedNotifier: expandedNotifier,
showHighlight: false, showHighlight: false,
children: [ children: [
SwitchListTile( if (canEnableErrorReporting)
value: currentIsErrorReportingEnabled, Selector<Settings, bool>(
onChanged: (v) => settings.isErrorReportingEnabled = v, selector: (context, s) => s.isErrorReportingEnabled,
title: Text(context.l10n.settingsEnableErrorReporting), builder: (context, current, child) => SwitchListTile(
), value: current,
SwitchListTile( onChanged: (v) => settings.isErrorReportingEnabled = v,
value: currentSaveSearchHistory, title: Text(context.l10n.settingsEnableErrorReporting),
onChanged: (v) { ),
settings.saveSearchHistory = v; ),
if (!v) { Selector<Settings, bool>(
settings.searchHistory = []; selector: (context, s) => s.saveSearchHistory,
} builder: (context, current, child) => SwitchListTile(
}, value: current,
title: Text(context.l10n.settingsSaveSearchHistory), onChanged: (v) {
settings.saveSearchHistory = v;
if (!v) {
settings.searchHistory = [];
}
},
title: Text(context.l10n.settingsSaveSearchHistory),
),
), ),
const HiddenFilterTile(), const HiddenFilterTile(),
const HiddenPathTile(), const HiddenPathTile(),

View file

@ -1,3 +1,4 @@
import 'package:aves/app_flavor.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/widgets/common/basic/labeled_checkbox.dart'; import 'package:aves/widgets/common/basic/labeled_checkbox.dart';
@ -100,16 +101,18 @@ class _WelcomePageState extends State<WelcomePage> {
} }
List<Widget> _buildBottomControls(BuildContext context) { List<Widget> _buildBottomControls(BuildContext context) {
final canEnableErrorReporting = context.select<AppFlavor, bool>((v) => v.canEnableErrorReporting);
final checkboxes = Column( final checkboxes = Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
LabeledCheckbox( if (canEnableErrorReporting)
value: settings.isErrorReportingEnabled, LabeledCheckbox(
onChanged: (v) { value: settings.isErrorReportingEnabled,
if (v != null) setState(() => settings.isErrorReportingEnabled = v); onChanged: (v) {
}, if (v != null) setState(() => settings.isErrorReportingEnabled = v);
text: context.l10n.welcomeCrashReportToggle, },
), text: context.l10n.welcomeCrashReportToggle,
),
LabeledCheckbox( LabeledCheckbox(
// key is expected by test driver // key is expected by test driver
key: const Key('agree-checkbox'), key: const Key('agree-checkbox'),

7
plugins/aves_report/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
.DS_Store
.dart_tool/
.packages
.pub/
build/

View file

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 18116933e77adc82f80866c928266a5b4f1ed645
channel: stable
project_type: plugin

View file

@ -0,0 +1 @@
include: ../../analysis_options.yaml

View file

@ -0,0 +1,21 @@
library aves_report;
import 'package:flutter/foundation.dart';
abstract class ReportService {
Future<void> init();
Map<String, String> get state;
Future<void> setCollectionEnabled(bool enabled);
Future<void> log(String message);
Future<void> setCustomKey(String key, Object value);
Future<void> setCustomKeys(Map<String, Object> map);
Future<void> recordError(dynamic exception, StackTrace? stack);
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails);
}

View file

@ -0,0 +1,65 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"

View file

@ -0,0 +1,16 @@
name: aves_report
version: 0.0.1
publish_to: none
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_lints:
flutter:

75
plugins/aves_report_console/.gitignore vendored Normal file
View file

@ -0,0 +1,75 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/ephemeral
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3

View file

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 18116933e77adc82f80866c928266a5b4f1ed645
channel: stable
project_type: package

View file

@ -0,0 +1 @@
include: ../../analysis_options.yaml

View file

@ -0,0 +1,30 @@
library aves_report_platform;
import 'package:aves_report/aves_report.dart';
import 'package:flutter/foundation.dart';
class PlatformReportService extends ReportService {
@override
Future<void> init() => SynchronousFuture(null);
@override
Future<void> log(String message) async => debugPrint('Report log with message=$message');
@override
Future<void> recordError(exception, StackTrace? stack) async => debugPrint('Report error with exception=$exception, stack=$stack');
@override
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails) async => debugPrint('Report Flutter error with details=$flutterErrorDetails');
@override
Future<void> setCollectionEnabled(bool enabled) => SynchronousFuture(null);
@override
Future<void> setCustomKey(String key, Object value) async => debugPrint('Report set key $key=$value');
@override
Future<void> setCustomKeys(Map<String, Object> map) async => debugPrint('Report set keys ${map.entries.map((kv) => '${kv.key}=${kv.value}').join(', ')}');
@override
Map<String, String> get state => {'Reporter': 'Console'};
}

View file

@ -0,0 +1,140 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
aves_report:
dependency: "direct main"
description:
path: "../aves_report"
relative: true
source: path
version: "0.0.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
firebase_core:
dependency: transitive
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
firebase_crashlytics:
dependency: transitive
description:
name: firebase_crashlytics
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4"
firebase_crashlytics_platform_interface:
dependency: transitive
description:
name: firebase_crashlytics_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"

View file

@ -0,0 +1,18 @@
name: aves_report_platform
version: 0.0.1
publish_to: none
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
aves_report:
path: ../aves_report
dev_dependencies:
flutter_lints:
flutter:

View file

@ -0,0 +1,75 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/ephemeral
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3

View file

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 18116933e77adc82f80866c928266a5b4f1ed645
channel: stable
project_type: package

View file

@ -0,0 +1 @@
include: ../../analysis_options.yaml

View file

@ -1,3 +1,8 @@
library aves_report_platform;
import 'dart:async';
import 'package:aves_report/aves_report.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart';
@ -5,32 +10,18 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:stack_trace/stack_trace.dart'; import 'package:stack_trace/stack_trace.dart';
abstract class ReportService { class PlatformReportService extends ReportService {
Future<void> init();
bool get isCollectionEnabled;
Future<void> setCollectionEnabled(bool enabled);
Future<void> log(String message);
Future<void> setCustomKey(String key, Object value);
Future<void> setCustomKeys(Map<String, Object> map);
Future<void> recordError(dynamic exception, StackTrace? stack);
Future<void> recordFlutterError(FlutterErrorDetails flutterErrorDetails);
}
class CrashlyticsReportService extends ReportService {
FirebaseCrashlytics get _instance => FirebaseCrashlytics.instance; FirebaseCrashlytics get _instance => FirebaseCrashlytics.instance;
@override @override
Future<void> init() => Firebase.initializeApp(); Future<void> init() => Firebase.initializeApp();
@override @override
bool get isCollectionEnabled => _instance.isCrashlyticsCollectionEnabled; Map<String, String> get state => {
'Reporter': 'Crashlytics',
'Firebase data collection enabled': '${Firebase.app().isAutomaticDataCollectionEnabled}',
'Crashlytics collection enabled': '${_instance.isCrashlyticsCollectionEnabled}',
};
@override @override
Future<void> setCollectionEnabled(bool enabled) async { Future<void> setCollectionEnabled(bool enabled) async {

View file

@ -0,0 +1,140 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
aves_report:
dependency: "direct main"
description:
path: "../aves_report"
relative: true
source: path
version: "0.0.1"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
firebase_crashlytics:
dependency: "direct main"
description:
name: firebase_crashlytics
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.4"
firebase_crashlytics_platform_interface:
dependency: transitive
description:
name: firebase_crashlytics_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"

View file

@ -0,0 +1,20 @@
name: aves_report_platform
version: 0.0.1
publish_to: none
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
aves_report:
path: ../aves_report
firebase_core:
firebase_crashlytics:
dev_dependencies:
flutter_lints:
flutter:

View file

@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "29.0.0" version: "30.0.0"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.6.0" version: "2.7.0"
archive: archive:
dependency: transitive dependency: transitive
description: description:
@ -36,6 +36,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.1" version: "2.8.1"
aves_report:
dependency: "direct main"
description:
path: "plugins/aves_report"
relative: true
source: path
version: "0.0.1"
aves_report_platform:
dependency: "direct main"
description:
path: "plugins/aves_report_crashlytics"
relative: true
source: path
version: "0.0.1"
barcode: barcode:
dependency: transitive dependency: transitive
description: description:
@ -288,12 +302,12 @@ packages:
source: hosted source: hosted
version: "6.1.2" version: "6.1.2"
firebase_core: firebase_core:
dependency: "direct main" dependency: transitive
description: description:
name: firebase_core name: firebase_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
firebase_core_platform_interface: firebase_core_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -309,19 +323,19 @@ packages:
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
firebase_crashlytics: firebase_crashlytics:
dependency: "direct main" dependency: transitive
description: description:
name: firebase_crashlytics name: firebase_crashlytics
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.3" version: "2.2.4"
firebase_crashlytics_platform_interface: firebase_crashlytics_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: firebase_crashlytics_platform_interface name: firebase_crashlytics_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.3" version: "3.1.4"
flex_color_picker: flex_color_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -385,14 +399,14 @@ packages:
name: flutter_markdown name: flutter_markdown
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.7" version: "0.6.8"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.0.4"
flutter_staggered_animations: flutter_staggered_animations:
dependency: "direct main" dependency: "direct main"
description: description:
@ -435,7 +449,7 @@ packages:
name: github name: github
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "8.2.1" version: "8.2.3"
glob: glob:
dependency: transitive dependency: transitive
description: description:
@ -596,7 +610,7 @@ packages:
name: mime name: mime
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.1"
motion_sensors: motion_sensors:
dependency: transitive dependency: transitive
description: description:
@ -736,7 +750,7 @@ packages:
name: pdf name: pdf
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.6.0" version: "3.6.1"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
@ -1163,7 +1177,7 @@ packages:
name: win32 name: win32
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.9" version: "2.2.10"
wkt_parser: wkt_parser:
dependency: transitive dependency: transitive
description: description:

View file

@ -7,11 +7,16 @@ publish_to: none
environment: environment:
sdk: '>=2.14.0 <3.0.0' sdk: '>=2.14.0 <3.0.0'
# use `scripts/apply_flavor_{flavor}.sh` to set the right dependencies for the flavor
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_localizations: flutter_localizations:
sdk: flutter sdk: flutter
aves_report:
path: plugins/aves_report
aves_report_platform:
path: plugins/aves_report_crashlytics
# TODO TLAD as of 2021/10/18, latest version (v0.11.0) is incompatible with Flutter v2.5 # TODO TLAD as of 2021/10/18, latest version (v0.11.0) is incompatible with Flutter v2.5
charts_flutter: charts_flutter:
git: git:
@ -33,8 +38,6 @@ dependencies:
git: git:
url: git://github.com/deckerst/fijkplayer.git url: git://github.com/deckerst/fijkplayer.git
ref: aves ref: aves
firebase_core:
firebase_crashlytics:
flex_color_picker: flex_color_picker:
fluster: fluster:
flutter_highlight: flutter_highlight:
@ -116,7 +119,7 @@ flutter:
# Test driver # Test driver
# run (any device): # run (any device):
# % flutter drive --flavor universal -t test_driver/driver_app.dart --profile # % flutter drive --flavor play -t test_driver/driver_play.dart --profile
# capture shaders in profile mode (real device only): # capture shaders in profile mode (real device only):
# % flutter drive --flavor universal -t test_driver/driver_app.dart --profile --cache-sksl --write-sksl-on-exit shaders.sksl.json # % flutter drive --flavor play -t test_driver/driver_play.dart --profile --cache-sksl --write-sksl-on-exit shaders.sksl.json

8
scripts/apply_flavor_izzy.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
PUBSPEC_PATH="../pubspec.yaml"
flutter clean
sed -i 's/aves_report_crashlytics/aves_report_console/g' "$PUBSPEC_PATH"
flutter pub get

8
scripts/apply_flavor_play.sh Executable file
View file

@ -0,0 +1,8 @@
#!/bin/bash
PUBSPEC_PATH="../pubspec.yaml"
flutter clean
sed -i 's/aves_report_console/aves_report_crashlytics/g' "$PUBSPEC_PATH"
flutter pub get

View file

@ -1,4 +1,4 @@
import 'package:aves/services/report_service.dart'; import 'package:aves_report/aves_report.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -7,7 +7,7 @@ class FakeReportService extends ReportService {
Future<void> init() => SynchronousFuture(null); Future<void> init() => SynchronousFuture(null);
@override @override
bool get isCollectionEnabled => false; Map<String, String> get state => {};
@override @override
Future<void> setCollectionEnabled(bool enabled) => SynchronousFuture(null); Future<void> setCollectionEnabled(bool enabled) => SynchronousFuture(null);

View file

@ -17,10 +17,10 @@ import 'package:aves/services/device_service.dart';
import 'package:aves/services/media/media_file_service.dart'; import 'package:aves/services/media/media_file_service.dart';
import 'package:aves/services/media/media_store_service.dart'; import 'package:aves/services/media/media_store_service.dart';
import 'package:aves/services/metadata/metadata_fetch_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/storage_service.dart';
import 'package:aves/services/window_service.dart'; import 'package:aves/services/window_service.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves_report/aves_report.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:latlong2/latlong.dart'; import 'package:latlong2/latlong.dart';

View file

@ -1,6 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:aves/main.dart' as app; import 'package:aves/main_play.dart' as app;
import 'package:aves/model/settings/enums.dart'; import 'package:aves/model/settings/enums.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/services/media/media_store_service.dart'; import 'package:aves/services/media/media_store_service.dart';