From cb213a709415c32b4b4528793d863c3449bc60b2 Mon Sep 17 00:00:00 2001
From: Jakub Homlala <1329033+jhomlala@users.noreply.github.com>
Date: Sun, 7 Jul 2024 13:14:03 +0200
Subject: [PATCH] refactor: Codebase refactor part 2 & bug fixes (#221)
* feat: introduced AliceConfiguration
* feat: introduced AliceConfiguration
* fix: fixed invalid count of http calls in notification
* feat: set configuration optional
* feat: added payload to notification
* fix: format
* fix: fixed tests
* fix: dart format
* feat: updated docs
* feat: updated metadata
* feat: updated tests
* refactor: refactored logger
* refactor: refactored codebase
* refactor: refactored codebase
* refactor: refactored codebase
* refactor: refactored codebase
* fix: fixed PR comments
* fix: fixed PR comments, updated metadata
* feat: updated metadata
* feat: dart fix
---
docs/config.md | 50 ++++++---
docs/install.md | 19 +++-
docs/other.md | 8 --
docs/usage.md | 9 --
examples/alice/lib/main.dart | 7 +-
examples/alice_chopper/lib/main.dart | 9 +-
examples/alice_dio/lib/main.dart | 9 +-
examples/alice_http/lib/main.dart | 9 +-
examples/alice_http_client/lib/main.dart | 9 +-
examples/alice_objectbox/lib/main.dart | 11 +-
packages/alice/CHANGELOG.md | 13 +++
packages/alice/README.md | 2 +
packages/alice/lib/alice.dart | 63 +----------
packages/alice/lib/core/alice_adapter.dart | 1 +
packages/alice/lib/core/alice_core.dart | 104 +++++++-----------
packages/alice/lib/core/alice_logger.dart | 75 ++++---------
.../alice/lib/core/alice_memory_storage.dart | 45 +++++---
.../alice/lib/core/alice_notification.dart | 20 ++--
packages/alice/lib/core/alice_storage.dart | 11 ++
packages/alice/lib/core/alice_store.dart | 3 -
.../alice/lib/core/alice_translations.dart | 11 +-
packages/alice/lib/core/alice_utils.dart | 1 +
.../lib/helper/alice_conversion_helper.dart | 24 ++--
.../alice/lib/helper/alice_export_helper.dart | 5 +-
.../alice/lib/helper/operating_system.dart | 6 +
.../alice/lib/model/alice_configuration.dart | 87 +++++++++++++++
packages/alice/lib/model/alice_http_call.dart | 12 +-
.../alice/lib/model/alice_translation.dart | 1 +
.../page/alice_call_details_page.dart | 25 +++--
.../widget/alice_call_response_screen.dart | 28 ++++-
.../page/alice_calls_list_page.dart | 9 +-
.../widget/alice_calls_list_screen.dart | 1 +
.../widget/alice_error_logs_widget.dart | 34 ++++++
.../widget/alice_inspector_screen.dart | 2 +
.../widget/alice_log_list_widget.dart | 28 +++--
.../calls_list/widget/alice_logs_screen.dart | 4 +-
.../widget/alice_raw_log_list_widger.dart | 66 ++++++-----
.../lib/ui/common/alice_context_ext.dart | 3 +
.../alice/lib/ui/common/alice_navigation.dart | 4 +-
packages/alice/lib/ui/common/alice_page.dart | 3 +-
packages/alice/lib/utils/alice_parser.dart | 2 +
packages/alice/lib/utils/curl.dart | 97 ++++++++--------
packages/alice/lib/utils/shake_detector.dart | 8 +-
packages/alice/pubspec.yaml | 2 +-
packages/alice/test/alice_test.dart | 84 ++++++++++++++
packages/alice/test/core/alice_core_test.dart | 19 ++--
.../alice/test/core/alice_logger_test.dart | 15 ---
.../test/core/alice_memory_storage_test.dart | 8 +-
.../test/helper/alice_export_helper_test.dart | 2 +-
.../alice/test/{ => mock}/mocked_data.dart | 0
packages/alice_dio/pubspec.yaml | 2 +-
packages/alice_objectbox/CHANGELOG.md | 3 +
.../alice_objectbox/lib/alice_objectbox.dart | 11 +-
.../lib/alice_objectbox_store.dart | 6 +-
.../lib/model/cached_alice_http_call.dart | 6 -
packages/alice_objectbox/pubspec.yaml | 2 +-
56 files changed, 649 insertions(+), 449 deletions(-)
delete mode 100644 packages/alice/lib/core/alice_store.dart
create mode 100644 packages/alice/lib/model/alice_configuration.dart
create mode 100644 packages/alice/lib/ui/calls_list/widget/alice_error_logs_widget.dart
create mode 100644 packages/alice/test/alice_test.dart
rename packages/alice/test/{ => mock}/mocked_data.dart (100%)
diff --git a/docs/config.md b/docs/config.md
index 8216ece3..91d08d89 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -1,59 +1,75 @@
## Configuration
+
1. Create Alice instance:
```dart
+
Alice alice = Alice();
```
2. Add navigator key to your application:
```dart
-MaterialApp( navigatorKey: alice.getNavigatorKey(), home: ...)
+MaterialApp(navigatorKey: alice.getNavigatorKey(), home: ...);
```
You need to add this navigator key in order to show inspector UI.
You can use also your navigator key in Alice:
```dart
-Alice alice = Alice(showNotification: true, navigatorKey: yourNavigatorKeyHere);
+
+Alice alice = Alice(configuration: AliceConfiguration(navigatorKey: yourNavigatorKeyHere));
```
If you need to pass navigatorKey lazily, you can use:
+
```dart
alice.setNavigatorKey(yourNavigatorKeyHere);
```
-This is minimal configuration required to run Alice. Can set optional settings in Alice constructor, which are presented below. If you don't want to change anything, you can move to Http clients configuration.
-### Additional settings
+This is minimal configuration required to run Alice. Can set optional settings in Alice constructor,
+which are presented below. If you don't want to change anything, you can move to Http clients
+configuration.
-You can set `showNotification` in Alice constructor to show notification. Clicking on this notification will open inspector.
-```dart
-Alice alice = Alice(..., showNotification: true);
-```
+### Alice configuration
-You can set `showInspectorOnShake` in Alice constructor to open inspector by shaking your device (default disabled):
+You can pass optional `AliceConfiguration` parameter to `Alice` instance.
+
+You can set `showNotification` in Alice constructor to show notification. Clicking on this
+notification will open inspector.
```dart
-Alice alice = Alice(..., showInspectorOnShake: true);
+
+Alice alice = Alice(configuration: AliceConfiguration(showNotification: true));
```
-If you want to pass another notification icon, you can use `notificationIcon` parameter. Default value is @mipmap/ic_launcher.
+You can set `showInspectorOnShake` in Alice constructor to open inspector by shaking your device (
+default disabled):
+
```dart
-Alice alice = Alice(..., notificationIcon: "myNotificationIconResourceName");
+
+Alice alice = Alice(configuration: AliceConfiguation(showInspectorOnShake: true));
```
-If you want to limit max numbers of HTTP calls saved in memory, you may use `maxCallsCount` parameter.
+If you want to pass another notification icon, you can use `notificationIcon` parameter. Default
+value is @mipmap/ic_launcher.
```dart
-Alice alice = Alice(..., maxCallsCount: 1000));
+
+Alice alice = Alice(configuration: AliceConfiguration(notificationIcon: "myNotificationIconResourceName"));
```
-If you want to change the Directionality of Alice, you can use the `directionality` parameter. If the parameter is set to null, the Directionality of the app will be used.
+If you want to change the Directionality of Alice, you can use the `directionality` parameter. If
+the parameter is set to null, the Directionality of the app will be used.
+
```dart
-Alice alice = Alice(..., directionality: TextDirection.ltr);
+
+Alice alice = Alice(configuration: AliceConfiguration(directionality: TextDirection.ltr));
```
If you want to hide share button, you can use `showShareButton` parameter.
+
```dart
-Alice alice = Alice(..., showShareButton: false);
+
+Alice alice = Alice(configuration: AliceConfiguration(showShareButton: false));
```
\ No newline at end of file
diff --git a/docs/install.md b/docs/install.md
index 005dca88..0a76f374 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -4,36 +4,51 @@
```yaml
dependencies:
- alice: ^1.0.0-dev9
+ alice: ^1.0.0-dev10
```
2. Choose adapter based on your HTTP client. **pubspec.yaml** file:
### Dio
+
```yaml
dependencies:
alice_dio: ^1.0.4
```
### Chopper
+
```yaml
dependencies:
alice_chopper: ^1.0.5
```
### Http
+
```yaml
dependencies:
alice_http: ^1.0.4
```
### Http Client
+
```yaml
dependencies:
alice_http_client: ^1.0.4
```
-3. Run `get` command:
+3. Choose optional database:
+
+### Objectbox
+
+```yaml
+dependencies:
+ objectbox: any
+ alice_objectbox: ^1.0.2
+```
+
+4. Run `get` command:
+
```bash
$ flutter packages get
```
\ No newline at end of file
diff --git a/docs/other.md b/docs/other.md
index 72d565ab..cb480550 100644
--- a/docs/other.md
+++ b/docs/other.md
@@ -8,14 +8,6 @@ You may need that if you won't use shake or notification:
alice.showInspector();
```
-## Saving calls
-
-Alice supports saving logs to your mobile device storage. In order to make save feature works, you need to add in your Android application manifest:
-
-```xml
-
-```
-
## Flutter logs
If you want to log Flutter logs in Alice, you may use these methods:
diff --git a/docs/usage.md b/docs/usage.md
index e9c10743..9f95ca27 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -105,15 +105,6 @@ httpClient
Setting up ObjectBox with Alice is simple, however, there are a few crucial steps which need to be followed.
-1. Add it to your dependencies
-
-```yaml
-dependencies:
- alice_objectbox: ^1.0.0
-```
-
-2. Follow the ObjectBox [example](https://github.com/objectbox/objectbox-dart/blob/main/objectbox/example/flutter/objectbox_demo/lib/main.dart)
-
```dart
Future main() async {
/// This is required so ObjectBox can get the application directory
diff --git a/examples/alice/lib/main.dart b/examples/alice/lib/main.dart
index 5f483389..6d2ddf3a 100644
--- a/examples/alice/lib/main.dart
+++ b/examples/alice/lib/main.dart
@@ -1,4 +1,5 @@
import 'package:alice/alice.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
@@ -11,11 +12,7 @@ class MyApp extends StatefulWidget {
}
class _MyAppState extends State {
- late final Alice _alice = Alice(
- showNotification: true,
- showInspectorOnShake: true,
- maxCallsCount: 1000,
- );
+ late final Alice _alice = Alice(configuration: AliceConfiguration());
@override
Widget build(BuildContext context) {
diff --git a/examples/alice_chopper/lib/main.dart b/examples/alice_chopper/lib/main.dart
index 20ef81c4..fce75b50 100644
--- a/examples/alice_chopper/lib/main.dart
+++ b/examples/alice_chopper/lib/main.dart
@@ -1,4 +1,5 @@
import 'package:alice/alice.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice_chopper/alice_chopper_adapter.dart';
import 'package:alice_chopper_example/interceptors/json_content_type_inerceptor.dart';
import 'package:alice_chopper_example/interceptors/json_headers_interceptor.dart';
@@ -35,11 +36,9 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
final AliceChopperAdapter _aliceChopperAdapter = AliceChopperAdapter();
- late final Alice _alice = Alice(
- showNotification: true,
- showInspectorOnShake: true,
- maxCallsCount: 1000,
- )..addAdapter(_aliceChopperAdapter);
+ final configuration = AliceConfiguration();
+ late final Alice _alice = Alice(configuration: configuration)
+ ..addAdapter(_aliceChopperAdapter);
late final ChopperClient _chopper = ChopperClient(
baseUrl: Uri.https('jsonplaceholder.typicode.com'),
diff --git a/examples/alice_dio/lib/main.dart b/examples/alice_dio/lib/main.dart
index c1913b67..d85883b2 100644
--- a/examples/alice_dio/lib/main.dart
+++ b/examples/alice_dio/lib/main.dart
@@ -1,6 +1,7 @@
import 'dart:io';
import 'package:alice/alice.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice_dio/alice_dio_adapter.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
@@ -19,11 +20,9 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
late final AliceDioAdapter _aliceDioAdapter = AliceDioAdapter();
- late final Alice _alice = Alice(
- showNotification: true,
- showInspectorOnShake: true,
- maxCallsCount: 1000,
- )..addAdapter(_aliceDioAdapter);
+ final configuration = AliceConfiguration();
+ late final Alice _alice = Alice(configuration: configuration)
+ ..addAdapter(_aliceDioAdapter);
late final Dio _dio = Dio(BaseOptions(followRedirects: false))
..interceptors.add(_aliceDioAdapter);
diff --git a/examples/alice_http/lib/main.dart b/examples/alice_http/lib/main.dart
index 3059cc06..249f6421 100644
--- a/examples/alice_http/lib/main.dart
+++ b/examples/alice_http/lib/main.dart
@@ -1,4 +1,5 @@
import 'package:alice/alice.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice_http/alice_http_adapter.dart';
import 'package:alice_http/alice_http_extensions.dart';
import 'package:flutter/material.dart';
@@ -16,11 +17,9 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
late final AliceHttpAdapter _aliceHttpAdapter = AliceHttpAdapter();
- late final Alice _alice = Alice(
- showNotification: true,
- showInspectorOnShake: true,
- maxCallsCount: 1000,
- )..addAdapter(_aliceHttpAdapter);
+ final configuration = AliceConfiguration();
+ late final Alice _alice = Alice(configuration: configuration)
+ ..addAdapter(_aliceHttpAdapter);
@override
Widget build(BuildContext context) {
diff --git a/examples/alice_http_client/lib/main.dart b/examples/alice_http_client/lib/main.dart
index ee35496c..0302e699 100644
--- a/examples/alice_http_client/lib/main.dart
+++ b/examples/alice_http_client/lib/main.dart
@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:alice/alice.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice_http_client/alice_http_client_adapter.dart';
import 'package:alice_http_client/alice_http_client_extensions.dart';
import 'package:flutter/material.dart';
@@ -21,11 +22,9 @@ class _MyAppState extends State {
late final AliceHttpClientAdapter _httpClientAdapter =
AliceHttpClientAdapter();
- late final Alice _alice = Alice(
- showNotification: true,
- showInspectorOnShake: true,
- maxCallsCount: 1000,
- )..addAdapter(_httpClientAdapter);
+ final configuration = AliceConfiguration();
+ late final Alice _alice = Alice(configuration: configuration)
+ ..addAdapter(_httpClientAdapter);
@override
Widget build(BuildContext context) {
diff --git a/examples/alice_objectbox/lib/main.dart b/examples/alice_objectbox/lib/main.dart
index b3662888..efbf2013 100644
--- a/examples/alice_objectbox/lib/main.dart
+++ b/examples/alice_objectbox/lib/main.dart
@@ -1,4 +1,5 @@
import 'package:alice/alice.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice_http/alice_http_adapter.dart';
import 'package:alice_http/alice_http_extensions.dart';
import 'package:alice_objectbox/alice_objectbox.dart';
@@ -34,14 +35,14 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State {
late final AliceHttpAdapter _aliceHttpAdapter = AliceHttpAdapter();
- late final Alice _alice = Alice(
- showNotification: true,
- showInspectorOnShake: true,
- maxCallsCount: 1000,
- aliceStorage: AliceObjectBox(
+ late final configuration = AliceConfiguration(
+ storage: AliceObjectBox(
store: widget.store,
maxCallsCount: 1000,
),
+ );
+ late final Alice _alice = Alice(
+ configuration: configuration
)..addAdapter(_aliceHttpAdapter);
@override
diff --git a/packages/alice/CHANGELOG.md b/packages/alice/CHANGELOG.md
index 73fb580f..5bb93eed 100644
--- a/packages/alice/CHANGELOG.md
+++ b/packages/alice/CHANGELOG.md
@@ -1,4 +1,15 @@
+# 1.0.0-dev.10
+
+* [BREAKING_CHANGE] Removed `maxCallsCount`. To change call count, use `storage` constructor parameter
+ with call count.
+* [BREAKING_CHANGE] Replaced configuration parameter of Alice with `AliceConfiguration`.
+* Fixed issue with invalid count of calls in notification.
+* Added payload to notification.
+* General refactor of code base.
+* Updated documentation.
+
# 1.0.0-dev.9
+
* Fixed saving issue with Android 13 onwards.
* Added unit tests.
* Updated CI/CD task for tests.
@@ -6,11 +17,13 @@
* Updated metadata.
# 1.0.0-dev.8
+
* Added storage abstractions (by Klemen Tusar https://github.com/techouse).
* Added in memory storage implementation (by Klemen Tusar https://github.com/techouse).
* Added translations.
# 1.0.0-dev.7
+
* Refactored UI code.
# 1.0.0-dev.6
diff --git a/packages/alice/README.md b/packages/alice/README.md
index 1e1fa832..a8d7a123 100644
--- a/packages/alice/README.md
+++ b/packages/alice/README.md
@@ -77,6 +77,8 @@ Alice is an HTTP Inspector tool for Flutter which helps debugging http requests.
✔️ Shake to open inspector
✔️ HTTP calls search
✔️ Flutter/Android logs
+✔️ ObjectBox storage
+
## Documentation
You can find documentation [here.](https://jhomlala.github.io/alice/)
\ No newline at end of file
diff --git a/packages/alice/lib/alice.dart b/packages/alice/lib/alice.dart
index c24407d5..cea943f8 100644
--- a/packages/alice/lib/alice.dart
+++ b/packages/alice/lib/alice.dart
@@ -1,85 +1,34 @@
import 'package:alice/core/alice_adapter.dart';
import 'package:alice/core/alice_core.dart';
-import 'package:alice/core/alice_logger.dart';
-import 'package:alice/core/alice_memory_storage.dart';
-import 'package:alice/core/alice_storage.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice/model/alice_http_call.dart';
import 'package:alice/model/alice_log.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
-export 'package:alice/core/alice_store.dart';
export 'package:alice/model/alice_log.dart';
export 'package:alice/core/alice_memory_storage.dart';
export 'package:alice/utils/alice_parser.dart';
class Alice {
- /// Should user be notified with notification when there's new request caught
- /// by Alice
- final bool showNotification;
-
- /// Should inspector be opened on device shake (works only with physical
- /// with sensors)
- final bool showInspectorOnShake;
-
- /// Icon url for notification
- final String notificationIcon;
-
- /// Max number of calls that are stored in memory. When count is reached, FIFO
- /// method queue will be used to remove elements.
- final int maxCallsCount;
-
- /// Directionality of app. Directionality of the app will be used if set to
- /// null.
- final TextDirection? directionality;
-
- /// Flag used to show/hide share button
- final bool? showShareButton;
-
/// Alice core instance
late final AliceCore _aliceCore;
- /// Alice storage instance
- final AliceStorage? _aliceStorage;
-
- /// Navigator key used for navigating to inspector
- GlobalKey? _navigatorKey;
-
/// Creates alice instance.
- Alice({
- GlobalKey? navigatorKey,
- this.showNotification = true,
- this.showInspectorOnShake = false,
- this.notificationIcon = '@mipmap/ic_launcher',
- this.maxCallsCount = 1000,
- this.directionality,
- this.showShareButton = true,
- AliceStorage? aliceStorage,
- }) : _navigatorKey = navigatorKey ?? GlobalKey(),
- _aliceStorage = aliceStorage {
+ Alice({AliceConfiguration? configuration}) {
_aliceCore = AliceCore(
- _navigatorKey,
- showNotification: showNotification,
- showInspectorOnShake: showInspectorOnShake,
- notificationIcon: notificationIcon,
- directionality: directionality,
- showShareButton: showShareButton,
- aliceStorage: _aliceStorage ??
- AliceMemoryStorage(
- maxCallsCount: maxCallsCount,
- ),
- aliceLogger: AliceLogger(),
+ configuration: configuration ?? AliceConfiguration(),
);
}
/// Set custom navigation key. This will help if there's route library.
void setNavigatorKey(GlobalKey navigatorKey) {
- _navigatorKey = navigatorKey;
- _aliceCore.navigatorKey = navigatorKey;
+ _aliceCore.setNavigatorKey(navigatorKey);
}
/// Get currently used navigation key
- GlobalKey? getNavigatorKey() => _navigatorKey;
+ GlobalKey? getNavigatorKey() =>
+ _aliceCore.configuration.navigatorKey;
/// Opens Http calls inspector. This will navigate user to the new fullscreen
/// page where all listened http calls can be viewed.
diff --git a/packages/alice/lib/core/alice_adapter.dart b/packages/alice/lib/core/alice_adapter.dart
index d0f5604c..c1116a51 100644
--- a/packages/alice/lib/core/alice_adapter.dart
+++ b/packages/alice/lib/core/alice_adapter.dart
@@ -4,5 +4,6 @@ import 'package:alice/core/alice_core.dart';
mixin AliceAdapter {
late final AliceCore aliceCore;
+ /// Injects [AliceCore] into adapter.
void injectCore(AliceCore aliceCore) => this.aliceCore = aliceCore;
}
diff --git a/packages/alice/lib/core/alice_core.dart b/packages/alice/lib/core/alice_core.dart
index ce5519b3..51b2473d 100644
--- a/packages/alice/lib/core/alice_core.dart
+++ b/packages/alice/lib/core/alice_core.dart
@@ -1,11 +1,11 @@
import 'dart:async' show FutureOr, StreamSubscription;
-import 'package:alice/core/alice_logger.dart';
import 'package:alice/core/alice_storage.dart';
import 'package:alice/core/alice_utils.dart';
import 'package:alice/helper/alice_export_helper.dart';
import 'package:alice/core/alice_notification.dart';
import 'package:alice/helper/operating_system.dart';
+import 'package:alice/model/alice_configuration.dart';
import 'package:alice/model/alice_export_result.dart';
import 'package:alice/model/alice_http_call.dart';
import 'package:alice/model/alice_http_error.dart';
@@ -15,37 +15,9 @@ import 'package:alice/ui/common/alice_navigation.dart';
import 'package:alice/utils/shake_detector.dart';
import 'package:flutter/material.dart';
-typedef AliceOnCallsChanged = Future Function(List? calls);
-
class AliceCore {
- /// Should user be notified with notification if there's new request caught
- /// by Alice
- final bool showNotification;
-
- /// Should inspector be opened on device shake (works only with physical
- /// with sensors)
- final bool showInspectorOnShake;
-
- /// Icon url for notification
- final String notificationIcon;
-
- /// Storage used for Alice to keep calls data.
- final AliceStorage _aliceStorage;
-
- /// Logger used for Alice to keep logs;
- final AliceLogger _aliceLogger;
-
- ///Directionality of app. If null then directionality of context will be used.
- final TextDirection? directionality;
-
- ///Flag used to show/hide share button
- final bool? showShareButton;
-
- /// Navigator key used for inspector navigator.
- GlobalKey? navigatorKey;
-
- /// Flag used to determine whether is inspector opened
- bool _isInspectorOpened = false;
+ /// Configuration of Alice
+ late AliceConfiguration _configuration;
/// Detector used to detect device shakes
ShakeDetector? _shakeDetector;
@@ -56,27 +28,21 @@ class AliceCore {
/// Subscription for call changes
StreamSubscription>? _callsSubscription;
+ /// Flag used to determine whether is inspector opened
+ bool _isInspectorOpened = false;
+
/// Creates alice core instance
- AliceCore(
- this.navigatorKey, {
- required this.showNotification,
- required this.showInspectorOnShake,
- required this.notificationIcon,
- required AliceStorage aliceStorage,
- required AliceLogger aliceLogger,
- this.directionality,
- this.showShareButton,
- }) : _aliceStorage = aliceStorage,
- _aliceLogger = aliceLogger {
+ AliceCore({required AliceConfiguration configuration}) {
+ _configuration = configuration;
_subscribeToCallChanges();
- if (showNotification) {
+ if (_configuration.showNotification) {
_notification = AliceNotification();
_notification?.configure(
- notificationIcon: notificationIcon,
+ notificationIcon: _configuration.notificationIcon,
openInspectorCallback: navigateToCallListScreen,
);
}
- if (showInspectorOnShake) {
+ if (_configuration.showInspectorOnShake) {
if (OperatingSystem.isAndroid || OperatingSystem.isMacOS) {
_shakeDetector = ShakeDetector.autoStart(
onPhoneShake: navigateToCallListScreen,
@@ -86,6 +52,14 @@ class AliceCore {
}
}
+ /// Returns current configuration
+ AliceConfiguration get configuration => _configuration;
+
+ /// Set custom navigation key. This will help if there's route library.
+ void setNavigatorKey(GlobalKey navigatorKey) {
+ _configuration = _configuration.copyWith(navigatorKey: navigatorKey);
+ }
+
/// Dispose subjects and subscriptions
void dispose() {
_shakeDetector?.stopListening();
@@ -95,7 +69,7 @@ class AliceCore {
/// Called when calls has been updated
Future _onCallsChanged(List? calls) async {
if (calls != null && calls.isNotEmpty) {
- final AliceStats stats = _aliceStorage.getStats();
+ final AliceStats stats = _configuration.aliceStorage.getStats();
_notification?.showStatsNotification(
context: getContext()!,
stats: stats,
@@ -105,7 +79,7 @@ class AliceCore {
/// Opens Http calls inspector. This will navigate user to the new fullscreen
/// page where all listened http calls can be viewed.
- void navigateToCallListScreen() {
+ Future navigateToCallListScreen() async {
final BuildContext? context = getContext();
if (context == null) {
AliceUtils.log(
@@ -116,56 +90,60 @@ class AliceCore {
}
if (!_isInspectorOpened) {
_isInspectorOpened = true;
- AliceNavigation.navigateToCallsList(core: this, logger: _aliceLogger)
- .then((_) => _isInspectorOpened = false);
+ await AliceNavigation.navigateToCallsList(core: this);
+ _isInspectorOpened = false;
}
}
/// Get context from navigator key. Used to open inspector route.
- BuildContext? getContext() => navigatorKey?.currentState?.overlay?.context;
+ BuildContext? getContext() =>
+ _configuration.navigatorKey?.currentState?.overlay?.context;
/// Add alice http call to calls subject
- FutureOr addCall(AliceHttpCall call) => _aliceStorage.addCall(call);
+ FutureOr addCall(AliceHttpCall call) =>
+ _configuration.aliceStorage.addCall(call);
/// Add error to existing alice http call
FutureOr addError(AliceHttpError error, int requestId) =>
- _aliceStorage.addError(error, requestId);
+ _configuration.aliceStorage.addError(error, requestId);
/// Add response to existing alice http call
FutureOr addResponse(AliceHttpResponse response, int requestId) =>
- _aliceStorage.addResponse(response, requestId);
+ _configuration.aliceStorage.addResponse(response, requestId);
/// Remove all calls from calls subject
- FutureOr removeCalls() => _aliceStorage.removeCalls();
+ FutureOr removeCalls() => _configuration.aliceStorage.removeCalls();
/// Selects call with given [requestId]. It may return null.
@protected
AliceHttpCall? selectCall(int requestId) =>
- _aliceStorage.selectCall(requestId);
+ _configuration.aliceStorage.selectCall(requestId);
/// Returns stream which returns list of HTTP calls
- Stream> get callsStream => _aliceStorage.callsStream;
+ Stream> get callsStream =>
+ _configuration.aliceStorage.callsStream;
/// Returns all stored HTTP calls.
- List getCalls() => _aliceStorage.getCalls();
+ List getCalls() => _configuration.aliceStorage.getCalls();
/// Save all calls to file.
- Future saveCallsToFile(BuildContext context) {
- return AliceExportHelper.saveCallsToFile(context, _aliceStorage.getCalls());
- }
+ Future saveCallsToFile(BuildContext context) =>
+ AliceExportHelper.saveCallsToFile(
+ context, _configuration.aliceStorage.getCalls());
/// Adds new log to Alice logger.
- void addLog(AliceLog log) => _aliceLogger.add(log);
+ void addLog(AliceLog log) => _configuration.aliceLogger.add(log);
/// Adds list of logs to Alice logger
- void addLogs(List logs) => _aliceLogger.addAll(logs);
+ void addLogs(List logs) => _configuration.aliceLogger.addAll(logs);
/// Returns flag which determines whether inspector is opened
bool get isInspectorOpened => _isInspectorOpened;
/// Subscribes to storage for call changes.
void _subscribeToCallChanges() {
- _callsSubscription = _aliceStorage.callsStream.listen(_onCallsChanged);
+ _callsSubscription =
+ _configuration.aliceStorage.callsStream.listen(_onCallsChanged);
}
/// Unsubscribes storage for call changes.
diff --git a/packages/alice/lib/core/alice_logger.dart b/packages/alice/lib/core/alice_logger.dart
index e63f5010..3f01e5da 100644
--- a/packages/alice/lib/core/alice_logger.dart
+++ b/packages/alice/lib/core/alice_logger.dart
@@ -2,77 +2,48 @@ import 'dart:io' show Process, ProcessResult;
import 'package:alice/helper/operating_system.dart';
import 'package:alice/model/alice_log.dart';
-import 'package:alice/utils/num_comparison.dart';
-import 'package:flutter/foundation.dart';
+import 'package:rxdart/rxdart.dart';
/// Logger used to handle logs from application.
class AliceLogger {
- AliceLogger({int? maximumSize = 1000}) : _maximumSize = maximumSize;
+ /// Maximum logs size. If 0, logs will be not rotated.
+ final int maximumSize;
- final ValueNotifier> _logs = ValueNotifier>([]);
+ /// Subject which keeps logs.
+ final BehaviorSubject> _logsSubject;
- ValueListenable> get listenable => _logs;
+ AliceLogger({required this.maximumSize})
+ : _logsSubject = BehaviorSubject.seeded([]);
- List get logs => listenable.value;
+ /// Getter of stream of logs
+ Stream> get logsStream => _logsSubject.stream;
- int? _maximumSize;
+ /// Getter of all logs
+ List get logs => _logsSubject.value;
- /// The maximum number of logs to store or `null` for unlimited storage.
- ///
- /// If more logs arrive, the oldest ones (based on their [
- /// AliceLog.timestamp]) will be removed.
- int? get maximumSize => _maximumSize;
-
- set maximumSize(int? value) {
- _maximumSize = maximumSize;
-
- if (value != null && logs.length > value) {
- _logs.value = logs.sublist(logs.length - value, logs.length);
- }
- }
-
- void addAll(List logs) {
+ /// Adds all logs.
+ void addAll(Iterable logs) {
for (var log in logs) {
add(log);
}
}
+ /// Add one log. It sorts logs after adding new element. If [maximumSize] is
+ /// set and max size is reached, first log will be deleted.
void add(AliceLog log) {
- late final int index;
- if (logs.isEmpty || !log.timestamp.isBefore(logs.last.timestamp)) {
- // Quick path as new logs are usually more recent.
- index = logs.length;
- } else {
- // Binary search to find the insertion index.
- int min = 0;
- int max = logs.length;
- while (min < max) {
- final int mid = min + ((max - min) >> 1);
- final AliceLog item = logs[mid];
- if (log.timestamp.isBefore(item.timestamp)) {
- max = mid;
- } else {
- min = mid + 1;
- }
- }
- assert(min == max, '');
- index = min;
+ final values = _logsSubject.value;
+ final count = values.length;
+ if (maximumSize > 0 && count >= maximumSize) {
+ values.removeAt(0);
}
- int startIndex = 0;
- if (maximumSize != null && logs.length.gte(maximumSize)) {
- if (index == 0) return;
- startIndex = logs.length - maximumSize! + 1;
- }
- _logs.value = [
- ...logs.sublist(startIndex, index),
- log,
- ...logs.sublist(index, logs.length),
- ];
+ values.add(log);
+ values.sort((log1, log2) => log1.timestamp.compareTo(log2.timestamp));
+ _logsSubject.add(values);
}
/// Clears all logs.
- void clearLogs() => _logs.value.clear();
+ void clearLogs() => _logsSubject.add([]);
/// Returns raw logs from Android via ADB.
Future getAndroidRawLogs() async {
diff --git a/packages/alice/lib/core/alice_memory_storage.dart b/packages/alice/lib/core/alice_memory_storage.dart
index dffbfaaf..bd7c603f 100644
--- a/packages/alice/lib/core/alice_memory_storage.dart
+++ b/packages/alice/lib/core/alice_memory_storage.dart
@@ -9,23 +9,28 @@ import 'package:alice/utils/num_comparison.dart';
import 'package:collection/collection.dart';
import 'package:rxdart/subjects.dart';
+/// Storage which uses memory to store calls data. It's a default storage
+/// method.
class AliceMemoryStorage implements AliceStorage {
AliceMemoryStorage({
required this.maxCallsCount,
- }) : callsSubject = BehaviorSubject.seeded([]),
+ }) : _callsSubject = BehaviorSubject.seeded([]),
assert(maxCallsCount > 0, 'Max calls count should be greater than 0');
-
@override
final int maxCallsCount;
- final BehaviorSubject> callsSubject;
+ /// Subject which stores all HTTP calls.
+ final BehaviorSubject> _callsSubject;
+ /// Stream which returns all HTTP calls on change.
@override
- Stream> get callsStream => callsSubject.stream;
+ Stream> get callsStream => _callsSubject.stream;
+ /// Returns all HTTP calls.
@override
- List getCalls() => callsSubject.value;
+ List getCalls() => _callsSubject.value;
+ /// Returns stats based on calls.
@override
AliceStats getStats() {
final List calls = getCalls();
@@ -45,30 +50,31 @@ class AliceMemoryStorage implements AliceStorage {
(call.response?.status.lt(400) ?? false))
.length,
errors: calls
- .where(
- (AliceHttpCall call) =>
- (call.response?.status.gte(400) ?? false) &&
- (call.response?.status.lt(600) ?? false),
- )
+ .where((AliceHttpCall call) =>
+ ((call.response?.status.gte(400) ?? false) &&
+ (call.response?.status.lt(600) ?? false)) ||
+ const [-1, 0].contains(call.response?.status))
.length,
loading: calls.where((AliceHttpCall call) => call.loading).length,
);
}
+ /// Adds new call to calls list.
@override
void addCall(AliceHttpCall call) {
- final int callsCount = callsSubject.value.length;
+ final int callsCount = _callsSubject.value.length;
if (callsCount >= maxCallsCount) {
- final List originalCalls = callsSubject.value;
+ final List originalCalls = _callsSubject.value;
originalCalls.removeAt(0);
originalCalls.add(call);
- callsSubject.add(originalCalls);
+ _callsSubject.add(originalCalls);
} else {
- callsSubject.add([...callsSubject.value, call]);
+ _callsSubject.add([..._callsSubject.value, call]);
}
}
+ /// Adds error to a specific call.
@override
void addError(AliceHttpError error, int requestId) {
final AliceHttpCall? selectedCall = selectCall(requestId);
@@ -78,9 +84,10 @@ class AliceMemoryStorage implements AliceStorage {
}
selectedCall.error = error;
- callsSubject.add([...callsSubject.value]);
+ _callsSubject.add([..._callsSubject.value]);
}
+ /// Adds response to a specific call.
@override
void addResponse(AliceHttpResponse response, int requestId) {
final AliceHttpCall? selectedCall = selectCall(requestId);
@@ -95,13 +102,15 @@ class AliceMemoryStorage implements AliceStorage {
..duration = response.time.millisecondsSinceEpoch -
(selectedCall.request?.time.millisecondsSinceEpoch ?? 0);
- callsSubject.add([...callsSubject.value]);
+ _callsSubject.add([..._callsSubject.value]);
}
+ /// Removes all calls.
@override
- void removeCalls() => callsSubject.add([]);
+ void removeCalls() => _callsSubject.add([]);
+ /// Searches for call with specific [requestId]. It may return null.
@override
- AliceHttpCall? selectCall(int requestId) => callsSubject.value
+ AliceHttpCall? selectCall(int requestId) => _callsSubject.value
.firstWhereOrNull((AliceHttpCall call) => call.id == requestId);
}
diff --git a/packages/alice/lib/core/alice_notification.dart b/packages/alice/lib/core/alice_notification.dart
index 41cbcfe4..555a0d0e 100644
--- a/packages/alice/lib/core/alice_notification.dart
+++ b/packages/alice/lib/core/alice_notification.dart
@@ -8,6 +8,10 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
/// Helper for displaying local notifications.
class AliceNotification {
+ static const String _payload = 'Alice';
+ static const String _channel = 'Alice';
+ static const String _callCount = '[callCount]';
+
/// Notification plugin instance
FlutterLocalNotificationsPlugin? _flutterLocalNotificationsPlugin;
@@ -32,9 +36,9 @@ class AliceNotification {
_openInspectorCallback = openInspectorCallback;
_notificationDetails = NotificationDetails(
android: AndroidNotificationDetails(
- 'Alice',
- 'Alice',
- channelDescription: 'Alice',
+ _channel,
+ _channel,
+ channelDescription: _channel,
enableVibration: false,
playSound: false,
largeIcon: DrawableResourceAndroidBitmap(notificationIcon),
@@ -99,8 +103,10 @@ class AliceNotification {
}
/// Formats [stats] for notification message.
- String _getNotificationMessage(
- {required BuildContext context, required AliceStats stats}) =>
+ String _getNotificationMessage({
+ required BuildContext context,
+ required AliceStats stats,
+ }) =>
[
if (stats.loading > 0)
'${context.i18n(AliceTranslationKey.notificationLoading)} ${stats.loading}',
@@ -136,10 +142,10 @@ class AliceNotification {
0,
context
.i18n(AliceTranslationKey.notificationTotalRequests)
- .replaceAll("[requestCount]", stats.total.toString()),
+ .replaceAll(_callCount, stats.total.toString()),
message,
_notificationDetails,
- payload: '',
+ payload: _payload,
);
_notificationMessageDisplayed = message;
diff --git a/packages/alice/lib/core/alice_storage.dart b/packages/alice/lib/core/alice_storage.dart
index d1808882..0f7f7f31 100644
--- a/packages/alice/lib/core/alice_storage.dart
+++ b/packages/alice/lib/core/alice_storage.dart
@@ -4,6 +4,7 @@ import 'dart:async' show FutureOr;
import 'package:alice/model/alice_http_error.dart';
import 'package:alice/model/alice_http_response.dart';
+/// Definition of call stats.
typedef AliceStats = ({
int total,
int successes,
@@ -12,22 +13,32 @@ typedef AliceStats = ({
int loading,
});
+/// Definition of storage
abstract interface class AliceStorage {
+ /// Stream which returns all HTTP calls on change.
abstract final Stream> callsStream;
+ /// Max calls number which should be stored.
abstract final int maxCallsCount;
+ /// Returns all HTTP calls.
List getCalls();
+ /// Returns stats based on calls.
AliceStats getStats();
+ /// Searches for call with specific [requestId]. It may return null.
AliceHttpCall? selectCall(int requestId);
+ /// Adds new call to calls list.
FutureOr addCall(AliceHttpCall call);
+ /// Adds error to a specific call.
FutureOr addError(AliceHttpError error, int requestId);
+ /// Adds response to a specific call.
FutureOr addResponse(AliceHttpResponse response, int requestId);
+ /// Removes all calls.
FutureOr removeCalls();
}
diff --git a/packages/alice/lib/core/alice_store.dart b/packages/alice/lib/core/alice_store.dart
deleted file mode 100644
index 1d97f0f9..00000000
--- a/packages/alice/lib/core/alice_store.dart
+++ /dev/null
@@ -1,3 +0,0 @@
-abstract interface class AliceStore {
- void clear();
-}
diff --git a/packages/alice/lib/core/alice_translations.dart b/packages/alice/lib/core/alice_translations.dart
index 9b585146..a8391c1f 100644
--- a/packages/alice/lib/core/alice_translations.dart
+++ b/packages/alice/lib/core/alice_translations.dart
@@ -1,8 +1,11 @@
import 'package:alice/model/alice_translation.dart';
+/// Class used to manage translations in Alice.
class AliceTranslations {
+ /// Contains list of translation data for all languages.
static final List _translations = _initialise();
+ /// Initialises translation data for all languages.
static List _initialise() {
List translations = [];
translations.add(_buildEnTranslations());
@@ -10,6 +13,7 @@ class AliceTranslations {
return translations;
}
+ /// Builds [AliceTranslationData] for english language.
static AliceTranslationData _buildEnTranslations() {
return AliceTranslationData(languageCode: "en", values: {
AliceTranslationKey.alice: "Alice",
@@ -85,6 +89,7 @@ class AliceTranslations {
AliceTranslationKey.callsListStats: "Stats",
AliceTranslationKey.callsListSave: "Save",
AliceTranslationKey.logsEmpty: "There are no logs to show",
+ AliceTranslationKey.logsError: "Failed to display error",
AliceTranslationKey.logsItemError: "Error:",
AliceTranslationKey.logsItemStackTrace: "Stack trace:",
AliceTranslationKey.logsCopied: "Copied to clipboard.",
@@ -121,7 +126,7 @@ class AliceTranslations {
AliceTranslationKey.notificationRedirect: "Redirect:",
AliceTranslationKey.notificationError: "Error:",
AliceTranslationKey.notificationTotalRequests:
- "Alice (total [requestCount] requests)",
+ "Alice (total [callCount] HTTP calls)",
AliceTranslationKey.saveDialogPermissionErrorTitle: "Permission error",
AliceTranslationKey.saveDialogPermissionErrorDescription:
"Permission not granted. Couldn't save logs.",
@@ -173,6 +178,7 @@ class AliceTranslations {
});
}
+ /// Builds [AliceTranslationData] for polish language.
static AliceTranslationData _buildPlTranslations() {
return AliceTranslationData(languageCode: "pl", values: {
AliceTranslationKey.alice: "Alice",
@@ -249,6 +255,7 @@ class AliceTranslations {
AliceTranslationKey.callsListStats: "Statystyki",
AliceTranslationKey.callsListSave: "Zapis",
AliceTranslationKey.logsEmpty: "Brak rezultatów",
+ AliceTranslationKey.logsError: "Problem z wyświetleniem logów.",
AliceTranslationKey.logsItemError: "Błąd:",
AliceTranslationKey.logsItemStackTrace: "Ślad stosu:",
AliceTranslationKey.logsCopied: "Skopiowano do schowka.",
@@ -285,7 +292,7 @@ class AliceTranslations {
AliceTranslationKey.notificationRedirect: "Przekierowanie:",
AliceTranslationKey.notificationError: "Błąd:",
AliceTranslationKey.notificationTotalRequests:
- "Alice (razem [requestCount] żądań)",
+ "Alice (razem [callCount] połączeń HTTP)",
AliceTranslationKey.saveDialogPermissionErrorTitle: "Błąd pozwolenia",
AliceTranslationKey.saveDialogPermissionErrorDescription:
"Pozwolenie nieprzyznane. Nie można zapisać logów.",
diff --git a/packages/alice/lib/core/alice_utils.dart b/packages/alice/lib/core/alice_utils.dart
index ee15a3cf..74b1ef61 100644
--- a/packages/alice/lib/core/alice_utils.dart
+++ b/packages/alice/lib/core/alice_utils.dart
@@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart' show kReleaseMode, debugPrint;
/// Utils used across multiple classes in app.
class AliceUtils {
+ /// Logs debug text.
static void log(String logMessage) {
if (!kReleaseMode) {
debugPrint(logMessage);
diff --git a/packages/alice/lib/helper/alice_conversion_helper.dart b/packages/alice/lib/helper/alice_conversion_helper.dart
index 0b80608c..1801993c 100644
--- a/packages/alice/lib/helper/alice_conversion_helper.dart
+++ b/packages/alice/lib/helper/alice_conversion_helper.dart
@@ -4,14 +4,20 @@ class AliceConversionHelper {
static const int _megabyteAsByte = 1000000;
static const int _secondAsMillisecond = 1000;
static const int _minuteAsMillisecond = 60000;
+ static const String _bytes = "B";
+ static const String _kiloBytes = "kB";
+ static const String _megaBytes = "MB";
+ static const String _milliseconds = "ms";
+ static const String _seconds = "s";
+ static const String _minutes = "min";
/// Format bytes text
static String formatBytes(int bytes) => switch (bytes) {
- int bytes when bytes < 0 => '-1 B',
- int bytes when bytes <= _kilobyteAsByte => '$bytes B',
+ int bytes when bytes < 0 => '-1 $_bytes',
+ int bytes when bytes <= _kilobyteAsByte => '$bytes $_bytes',
int bytes when bytes <= _megabyteAsByte =>
- '${_formatDouble(bytes / _kilobyteAsByte)} kB',
- _ => '${_formatDouble(bytes / _megabyteAsByte)} MB',
+ '${_formatDouble(bytes / _kilobyteAsByte)} $_kiloBytes',
+ _ => '${_formatDouble(bytes / _megabyteAsByte)} $_megaBytes',
};
/// Formats double with two numbers after dot.
@@ -20,18 +26,18 @@ class AliceConversionHelper {
/// Format time in milliseconds
static String formatTime(int timeInMillis) {
if (timeInMillis < 0) {
- return '-1 ms';
+ return '-1 $_milliseconds';
}
if (timeInMillis <= _secondAsMillisecond) {
- return '$timeInMillis ms';
+ return '$timeInMillis $_milliseconds';
}
if (timeInMillis <= _minuteAsMillisecond) {
- return '${_formatDouble(timeInMillis / _secondAsMillisecond)} s';
+ return '${_formatDouble(timeInMillis / _secondAsMillisecond)} $_seconds';
}
final Duration duration = Duration(milliseconds: timeInMillis);
- return '${duration.inMinutes} min ${duration.inSeconds.remainder(60)} s '
- '${duration.inMilliseconds.remainder(1000)} ms';
+ return '${duration.inMinutes} $_minutes ${duration.inSeconds.remainder(60)} $_seconds '
+ '${duration.inMilliseconds.remainder(1000)} $_milliseconds';
}
}
diff --git a/packages/alice/lib/helper/alice_export_helper.dart b/packages/alice/lib/helper/alice_export_helper.dart
index 7e956335..5499937e 100644
--- a/packages/alice/lib/helper/alice_export_helper.dart
+++ b/packages/alice/lib/helper/alice_export_helper.dart
@@ -20,6 +20,7 @@ import 'package:share_plus/share_plus.dart';
class AliceExportHelper {
static const JsonEncoder _encoder = JsonEncoder.withIndent(' ');
+ static const String _fileName = "alice_log";
/// Format log based on [call] and tries to share it.
static Future shareCall({
@@ -97,7 +98,7 @@ class AliceExportHelper {
final Directory externalDir = await getApplicationCacheDirectory();
final String fileName =
- 'alice_log_${DateTime.now().millisecondsSinceEpoch}.txt';
+ '${_fileName}_${DateTime.now().millisecondsSinceEpoch}.txt';
final File file = File('${externalDir.path}/$fileName')..createSync();
final IOSink sink = file.openWrite(mode: FileMode.append)
..write(await _buildAliceLog(context: context));
@@ -199,7 +200,7 @@ class AliceExportHelper {
'--------------------------------------------\n',
'${context.i18n(AliceTranslationKey.saveLogCurl)}\n',
'--------------------------------------------\n',
- getCurlCommand(call),
+ Curl.getCurlCommand(call),
'\n',
'==============================================\n',
'\n',
diff --git a/packages/alice/lib/helper/operating_system.dart b/packages/alice/lib/helper/operating_system.dart
index 44b5941a..21200b61 100644
--- a/packages/alice/lib/helper/operating_system.dart
+++ b/packages/alice/lib/helper/operating_system.dart
@@ -9,15 +9,21 @@ abstract class OperatingSystem {
static const String macos = 'macos';
static const String windows = 'windows';
+ /// Flag which determines whether current platform is Android.
static bool get isAndroid => defaultTargetPlatform == TargetPlatform.android;
+ /// Flag which determines whether current platform is iOS.
static bool get isIOS => defaultTargetPlatform == TargetPlatform.iOS;
+ /// Flag which determines whether current platform is MacOS.
static bool get isMacOS => defaultTargetPlatform == TargetPlatform.macOS;
+ /// Flag which determines whether current platform is Windows.
static bool get isWindows => defaultTargetPlatform == TargetPlatform.windows;
+ /// Flag which determines whether current platform is Linux.
static bool get isLinux => defaultTargetPlatform == TargetPlatform.linux;
+ /// Flag which determines whether current platform is Fuchsia.
static bool get isFuchsia => defaultTargetPlatform == TargetPlatform.fuchsia;
}
diff --git a/packages/alice/lib/model/alice_configuration.dart b/packages/alice/lib/model/alice_configuration.dart
new file mode 100644
index 00000000..e9e6d6ca
--- /dev/null
+++ b/packages/alice/lib/model/alice_configuration.dart
@@ -0,0 +1,87 @@
+import 'package:alice/core/alice_logger.dart';
+import 'package:alice/core/alice_memory_storage.dart';
+import 'package:alice/core/alice_storage.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter/widgets.dart';
+
+class AliceConfiguration with EquatableMixin {
+ /// Default max calls count used in default memory storage.
+ static const _defaultMaxCalls = 1000;
+
+ /// Default max logs count.
+ static const _defaultMaxLogs = 1000;
+
+ /// Should user be notified with notification when there's new request caught
+ /// by Alice. Default value is true.
+ final bool showNotification;
+
+ /// Should inspector be opened on device shake (works only with physical
+ /// with sensors). Default value is true.
+ final bool showInspectorOnShake;
+
+ /// Icon url for notification. Default value is '@mipmap/ic_launcher'.
+ final String notificationIcon;
+
+ /// Directionality of app. Directionality of the app will be used if set to
+ /// null. Default value is null.
+ final TextDirection? directionality;
+
+ /// Flag used to show/hide share button
+ final bool showShareButton;
+
+ /// Navigator key used to open inspector. Default value is null.
+ final GlobalKey? navigatorKey;
+
+ /// Storage where calls will be saved. The default storage is memory storage.
+ final AliceStorage aliceStorage;
+
+ /// Logger instance.
+ final AliceLogger aliceLogger;
+
+ AliceConfiguration({
+ this.showNotification = true,
+ this.showInspectorOnShake = true,
+ this.notificationIcon = '@mipmap/ic_launcher',
+ this.directionality,
+ this.showShareButton = true,
+ GlobalKey? navigatorKey,
+ AliceStorage? storage,
+ AliceLogger? logger,
+ }) : aliceStorage =
+ storage ?? AliceMemoryStorage(maxCallsCount: _defaultMaxCalls),
+ navigatorKey = navigatorKey ?? GlobalKey(),
+ aliceLogger = logger ?? AliceLogger(maximumSize: _defaultMaxLogs);
+
+ AliceConfiguration copyWith({
+ GlobalKey? navigatorKey,
+ bool? showNotification,
+ bool? showInspectorOnShake,
+ String? notificationIcon,
+ TextDirection? directionality,
+ bool? showShareButton,
+ AliceStorage? aliceStorage,
+ AliceLogger? aliceLogger,
+ }) =>
+ AliceConfiguration(
+ showNotification: showNotification ?? this.showNotification,
+ showInspectorOnShake: showInspectorOnShake ?? this.showInspectorOnShake,
+ notificationIcon: notificationIcon ?? this.notificationIcon,
+ directionality: directionality ?? this.directionality,
+ showShareButton: showShareButton ?? this.showShareButton,
+ navigatorKey: navigatorKey ?? this.navigatorKey,
+ storage: aliceStorage ?? this.aliceStorage,
+ logger: aliceLogger ?? this.aliceLogger,
+ );
+
+ @override
+ List