Compare commits

..

30 Commits

Author SHA1 Message Date
Sergey Penkovsky
20e44beea7 chore(release): publish packages
- cherrypick@2.1.0
 - cherrypick_flutter@1.1.1
2025-05-19 10:12:32 +03:00
Sergey Penkovsky
0b3d10b88d Merge pull request #7 from pese-git/develop 2025-05-19 09:24:52 +03:00
Sergey Penkovsky
ed43bf78b8 hide test 2025-05-18 22:59:15 +03:00
Sergey Penkovsky
3cd15bc0c1 hide test 2025-05-18 16:48:37 +03:00
Sergey Penkovsky
bf1b0bd215 fix build scripts 2025-05-18 16:41:48 +03:00
Sergey Penkovsky
9bce40735b init di 2025-05-16 18:09:14 +03:00
Sergey Penkovsky
5cab9164ce modified build scripts 2025-05-16 17:58:02 +03:00
Sergey Penkovsky
0c5db63961 fixed warnings 2025-05-16 17:57:40 +03:00
Sergey Penkovsky
7740717fce implement example 2025-05-16 17:56:57 +03:00
Sergey Penkovsky
a7dc2e0f27 chore(release): publish packages
- cherrypick@2.1.0-dev.1
 - cherrypick_flutter@1.1.1-dev.1
2025-05-16 17:32:26 +03:00
Sergey Penkovsky
cb5f0b23d2 implement example 2025-05-16 17:32:26 +03:00
Sergey Penkovsky
c1b2f9c260 doc: update README 2025-05-16 17:32:26 +03:00
Sergey Penkovsky
80c121d2c9 chore(release): publish packages
- cherrypick@2.1.0-dev.0
 - cherrypick_flutter@1.1.1-dev.0
2025-05-16 17:32:26 +03:00
Sergey Penkovsky
3d24f01e3e doc: update README and example 2025-05-16 17:32:26 +03:00
Sergey Penkovsky
2c39ee48ad implement test 2025-05-16 17:32:26 +03:00
Sergey Penkovsky
28035a1ccd fix warnings 2025-05-16 17:32:25 +03:00
Sergey Penkovsky
1b5cc64324 feat: Add async dependency resolution and enhance example
- Implemented async provider methods `toProvideAsync` and `toProvideAsyncWithParams` in `Binding` class, allowing asynchronous initialization with dynamic parameters.
- Added typedefs `AsyncProvider<T>` and `AsyncProviderWithParams<T>` for better type clarity with async operations.
- Introduced async resolution methods `resolveAsync` and `tryResolveAsync` in `Scope` for resolving asynchronous dependencies.
- Updated example in `main.dart` to demonstrate async dependency resolution capabilities.
  - Modified `FeatureModule` to utilize async providers for `DataRepository` and `DataBloc`.
  - Replaced synchronous resolution with `resolveAsync` where applicable.
  - Handled potential errors in dependency resolution with try-catch.
- Removed unnecessary whitespace for cleaner code formatting.
2025-05-16 17:31:58 +03:00
Sergey Penkovsky
e0e2408bc5 fix: fix warning 2025-05-16 17:31:40 +03:00
Sergey Penkovsky
2fb91ca7cc fix: fix warning 2025-05-16 17:31:23 +03:00
Sergey Penkovsky
f23b14c13b docs: add CONTRIBUTORS.md 2025-05-16 16:43:23 +03:00
Sergey Penkovsky
9255dc2bc3 Update pipeline.yml 2025-05-16 14:17:52 +03:00
Sergey Penkovsky
0d2a6ef023 Update pipeline.yml 2025-05-16 14:11:22 +03:00
Sergey Penkovsky
ec977c06b2 Create pipeline.yml 2025-05-16 14:09:10 +03:00
Sergey Penkovsky
155e5f12a8 fix: fix warnings 2025-05-16 13:10:57 +03:00
Sergey Penkovsky
c5d17e372c fix: fix warnings 2025-05-16 13:06:46 +03:00
Sergey Penkovsky
dba52ccf82 doc: update readme 2025-05-16 13:02:32 +03:00
Sergey Penkovsky
33c97bdf34 formatted changelog 2025-05-16 12:52:59 +03:00
Sergey Penkovsky
e2562d22bb chore(release): publish packages
- cherrypick@2.0.2
 - cherrypick_flutter@1.1.1
2025-05-16 12:46:16 +03:00
Sergey Penkovsky
1a6e3d0b97 Merge pull request #6 from pese-git/fix/resolve_with_params
fix: support passing params when resolving dependency recursively in …
2025-05-16 12:43:42 +03:00
yarashevich_kv
ea8ff1da83 fix: support passing params when resolving dependency recursively in parent scope. 2025-05-16 10:13:59 +03:00
66 changed files with 2348 additions and 234 deletions

38
.github/workflows/pipeline.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Melos + FVM CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
# также актуализация Flutter, если нужен fvm
- name: Install FVM
run: dart pub global activate fvm
- name: Install Flutter version via FVM
run: fvm install
# ВАЖНО: активируем melos через flutter, чтобы не было несовместимости
- name: Install Melos
run: fvm flutter pub global activate melos
- name: Bootstrap workspace
run: fvm flutter pub global run melos bootstrap
- name: CodeGen
run: fvm flutter pub global run melos run codegen
- name: Analyze all packages
run: fvm flutter pub global run melos run analyze
- name: Run all tests
run: fvm flutter pub global run melos run test

5
.gitignore vendored
View File

@@ -7,6 +7,11 @@
.idea/
.vscode/
**/*.g.dart
**/*.gr.dart
**/*.freezed.dart
pubspec_overrides.yaml
melos_cherrypick.iml

View File

@@ -3,6 +3,90 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2025-05-19
### Changes
---
Packages with breaking changes:
- [`cherrypick_flutter` - `v1.1.1`](#cherrypick_flutter---v111)
Packages with other changes:
- [`cherrypick` - `v2.1.0`](#cherrypick---v210)
Packages graduated to a stable release (see pre-releases prior to the stable version for changelog entries):
- `cherrypick` - `v2.1.0`
- `cherrypick_flutter` - `v1.1.1`
---
#### `cherrypick_flutter` - `v1.1.1`
#### `cherrypick` - `v2.1.0`
## 2025-05-16
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`cherrypick` - `v2.1.0-dev.1`](#cherrypick---v210-dev1)
- [`cherrypick_flutter` - `v1.1.1-dev.1`](#cherrypick_flutter---v111-dev1)
---
#### `cherrypick` - `v2.1.0-dev.1`
- **FIX**: fix warnings.
- **FIX**: fix warnings.
- **FIX**: support passing params when resolving dependency recursively in parent scope.
- **FEAT**: Add async dependency resolution and enhance example.
- **FEAT**: Add async dependency resolution and enhance example.
#### `cherrypick_flutter` - `v1.1.1-dev.1`
- **FIX**: fix warnings.
## 2025-05-16
### Changes
---
Packages with breaking changes:
- There are no breaking changes in this release.
Packages with other changes:
- [`cherrypick` - `v2.0.2`](#cherrypick---v202)
- [`cherrypick_flutter` - `v1.1.1`](#cherrypick_flutter---v111)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `cherrypick_flutter` - `v1.1.1`
---
#### `cherrypick` - `v2.0.2`
- **FIX**: support passing params when resolving dependency recursively in parent scope.
## 2025-05-03
### Changes

4
CONTRIBUTORS.md Normal file
View File

@@ -0,0 +1,4 @@
# Contributors
- Sergey Penkovsky <sergey.penkovsky@gmail.com>
- Klim Yaroshevich <yarashevich_kv@st.by>

View File

@@ -93,7 +93,7 @@ We welcome contributions from the community. Feel free to open issues or submit
## License
This project is licensed under the Apache License 2.0. You may obtain a copy of the License at [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).
This project is licensed under the Apache License 2.0. You may obtain a copy of the License at [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
## Links

View File

@@ -19,3 +19,6 @@ doc/api/
*.js_
*.js.deps
*.js.map
# FVM Version Cache
.fvm/

View File

@@ -1,54 +1,60 @@
## 2.1.0
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 2.1.0-dev.1
- **FIX**: fix warnings.
- **FIX**: fix warnings.
- **FIX**: support passing params when resolving dependency recursively in parent scope.
- **FEAT**: Add async dependency resolution and enhance example.
- **FEAT**: Add async dependency resolution and enhance example.
## 2.0.2
- **FIX**: support passing params when resolving dependency recursively in parent scope.
## 2.1.0-dev.0
- **FEAT**: Add async dependency resolution and enhance example.
## 2.0.1
- **FIX**: fix warning.
- **FIX**: fix warning.
## 2.0.0
- **FEAT**: support for Dart 3.0.
## 1.1.0
- **FEAT**: verified Dart 3.0 support.
# Changelog
## 1.0.4
- **FIX**: Fixed exception "ConcurrentModificationError".
2.0.0 supported Dart 3.0
## 1.0.3
- **FEAT**: Added provider with params.
---
## 1.0.2
- **DOCS**: Updated docs and fixed syntax error.
1.1.0 cheked support Dart 3.0
## 1.0.1
- **FIX**: Fixed syntax error.
---
## 1.0.0
- **REFACTOR**: Refactored code and added experimental API.
1.0.4 Fixed exception "ConcurrentModificationError"
## 0.1.2+1
- **FIX**: Fixed initialization error.
---
## 0.1.2
- **FIX**: Fixed warnings in code.
1.0.3 Added provider with params
## 0.1.1+2
- **MAINT**: Updated libraries and fixed warnings.
---
## 0.1.1+1
- **MAINT**: Updated pubspec and readme.md.
1.0.2 Updated doc and fixed syntax error
## 0.1.1
- **MAINT**: Updated pubspec.
---
1.0.1 Fixed syntax error
---
1.0.0 Refactored code and added experimental api
---
0.1.2+1 Fixed initializtaion error
---
0.1.2 Fixed warnings in code
---
0.1.1+2 Updated libraries and fixed warnings
---
0.1.1+1 Updated pubspec and readme.md
---
0.1.1 Updated pubspec
---
0.1.0 Initial release
---
## 0.1.0
- **INIT**: Initial release.

View File

@@ -1,31 +1,43 @@
# CherryPick Flutter
`cherrypick_flutter` is a powerful Flutter library for managing and accessing dependencies within your application through a root scope context using `CherryPickProvider`. It offers simplified dependency injection, making your application more modular and test-friendly.
`cherrypick_flutter` is a robust Flutter library designed for managing and accessing dependencies using a scope context provided by `CherryPickProvider`. It enhances your application's modularity and testability by simplifying dependency injection.
## Quick Start
### Main Components in Dependency Injection (DI)
### Core Components of Dependency Injection (DI)
#### Binding
A Binding is a custom instance configurator, essential for setting up dependencies. It offers the following key methods:
A Binding is a custom instance configurator crucial for setting up dependencies. It offers the following key methods:
- `toInstance()`: Directly provides an initialized instance.
- `toProvide()`: Accepts a provider function or constructor for lazy initialization.
- `withName()`: Assigns a name to an instance, allowing for retrieval by name.
- `singleton()`: Marks the instance as a singleton, ensuring only one instance exists in the scope.
- `toProvide()`: Accepts a provider function for lazy initialization.
- `toProvideAsync()`: Accepts an asynchronous provider for lazy initialization.
- `toProvideWithParams()`: Accepts a provider function requiring dynamic parameters.
- `toProvideAsyncWithParams()`: Accepts an asynchronous provider requiring dynamic parameters.
- `withName()`: Assigns a name for instance retrieval by name.
- `singleton()`: Marks the instance as a singleton, ensuring only one instance exists within the scope.
##### Example:
```dart
// Direct instance initialization with toInstance()
// Direct instance initialization using toInstance()
Binding<String>().toInstance("hello world");
// Or use a provider for lazy initialization
// Lazy initialization via provider
Binding<String>().toProvide(() => "hello world");
// Named instance
Binding<String>().withName("my_string").toInstance("hello world");
// Asynchronous lazy initialization
Binding<String>().toProvideAsync(() async => "hello async world");
/ Asynchronous lazy initialization with dynamic parameters
Binding<String>().toProvideAsyncWithParams((params) async => "hello $params");
// Initialization with dynamic parameters
Binding<String>().toProvideWithParams((params) => "hello $params");
// Named instance for resolution
Binding<String>().toProvide(() => "hello world").withName("my_string").toInstance("hello world");
// Singleton instance
Binding<String>().toProvide(() => "hello world").singleton();
@@ -33,7 +45,7 @@ Binding<String>().toProvide(() => "hello world").singleton();
#### Module
A Module encapsulates bindings, allowing you to organize dependencies logically. To create a custom module, implement the `void builder(Scope currentScope)` method.
A Module encapsulates bindings, logically organizing dependencies. Implement the `void builder(Scope currentScope)` method to create a custom module.
##### Example:
@@ -48,13 +60,13 @@ class AppModule extends Module {
#### Scope
A Scope is the container that manages your dependency tree, holding modules and instances. Use the scope to access dependencies with the `resolve<T>()` method.
A Scope manages your dependency tree, holding modules and instances. Use the scope to access dependencies with `resolve<T>()` or `resolveAsync<T>()` for asynchronous operations.
##### Example:
```dart
// Open the main scope
final rootScope = Cherrypick.openRootScope();
final rootScope = CherryPick.openRootScope();
// Install custom modules
rootScope.installModules([AppModule()]);
@@ -62,13 +74,16 @@ rootScope.installModules([AppModule()]);
// Resolve an instance
final str = rootScope.resolve<String>();
// Asynchronously resolve an instance
final asyncStr = await rootScope.resolveAsync<String>();
// Close the main scope
Cherrypick.closeRootScope();
CherryPick.closeRootScope();
```
## Example Application
The following example demonstrates module setup, scope management, and dependency resolution.
The following example demonstrates module setup, scope management, and dependency resolution (both synchronous and asynchronous).
```dart
import 'dart:async';
@@ -84,26 +99,30 @@ class AppModule extends Module {
}
class FeatureModule extends Module {
bool isMock;
final bool isMock;
FeatureModule({required this.isMock});
@override
void builder(Scope currentScope) {
// Using toProvideAsync for async initialization
bind<DataRepository>()
.withName("networkRepo")
.toProvide(
() => NetworkDataRepository(
currentScope.resolve<ApiClient>(
named: isMock ? "apiClientMock" : "apiClientImpl",
),
),
)
.toProvideAsync(() async {
final client = await Future.delayed(
Duration(milliseconds: 100),
() => currentScope.resolve<ApiClient>(
named: isMock ? "apiClientMock" : "apiClientImpl"));
return NetworkDataRepository(client);
})
.singleton();
bind<DataBloc>().toProvide(
() => DataBloc(
currentScope.resolve<DataRepository>(named: "networkRepo"),
),
// Asynchronous initialization of DataBloc
bind<DataBloc>().toProvideAsync(
() async {
final repo = await currentScope.resolveAsync<DataRepository>(named: "networkRepo");
return DataBloc(repo);
},
);
}
}
@@ -117,7 +136,8 @@ void main() async {
.openSubScope("featureScope")
.installModules([FeatureModule(isMock: true)]);
final dataBloc = subScope.resolve<DataBloc>();
// Asynchronous instance resolution
final dataBloc = await subScope.resolveAsync<DataBloc>();
dataBloc.data.listen((d) => print('Received data: $d'),
onError: (e) => print('Error: $e'), onDone: () => print('DONE'));
@@ -128,7 +148,7 @@ class DataBloc {
final DataRepository _dataRepository;
Stream<String> get data => _dataController.stream;
StreamController<String> _dataController = new StreamController.broadcast();
StreamController<String> _dataController = StreamController.broadcast();
DataBloc(this._dataRepository);
@@ -185,6 +205,8 @@ class ApiClientImpl implements ApiClient {
- [x] Main Scope and Sub Scopes
- [x] Named Instance Initialization
- [x] Asynchronous Dependency Resolution
- [x] Dynamic Parameter Support for Providers
## Contributing

View File

@@ -1,39 +1,38 @@
import 'dart:async';
import 'package:cherrypick/cherrypick.dart';
import 'package:meta/meta.dart';
import 'package:cherrypick/cherrypick.dart';
class AppModule extends Module {
@override
void builder(Scope currentScope) {
bind<ApiClient>().withName('apiClientMock').toInstance(ApiClientMock());
bind<ApiClient>().withName('apiClientImpl').toInstance(ApiClientImpl());
bind<ApiClient>().withName("apiClientMock").toInstance(ApiClientMock());
bind<ApiClient>().withName("apiClientImpl").toInstance(ApiClientImpl());
}
}
class FeatureModule extends Module {
bool isMock;
final bool isMock;
FeatureModule({required this.isMock});
@override
void builder(Scope currentScope) {
bind<DataRepository>()
.withName('networkRepo')
.toProvide(
() => NetworkDataRepository(
currentScope.resolve<ApiClient>(
named: isMock ? 'apiClientMock' : 'apiClientImpl',
),
),
)
.singleton();
// Using toProvideAsync for async initialization
bind<DataRepository>().withName("networkRepo").toProvideAsync(() async {
final client = await Future.delayed(
Duration(milliseconds: 100),
() => currentScope.resolve<ApiClient>(
named: isMock ? "apiClientMock" : "apiClientImpl"));
return NetworkDataRepository(client);
}).singleton();
bind<DataBloc>().toProvideWithParams(
(param) => DataBloc(
currentScope.resolve<DataRepository>(named: 'networkRepo'),
param,
),
// Asynchronous initialization of DataBloc
bind<DataBloc>().toProvideAsync(
() async {
final repo = await currentScope.resolveAsync<DataRepository>(
named: "networkRepo");
return DataBloc(repo);
},
);
}
}
@@ -44,10 +43,11 @@ void main() async {
]);
final subScope = scope
.openSubScope('featureScope')
.openSubScope("featureScope")
.installModules([FeatureModule(isMock: true)]);
final dataBloc = subScope.resolve<DataBloc>(params: 'PARAMETER');
// Asynchronous instance resolution
final dataBloc = await subScope.resolveAsync<DataBloc>();
dataBloc.data.listen((d) => print('Received data: $d'),
onError: (e) => print('Error: $e'), onDone: () => print('DONE'));
@@ -60,13 +60,11 @@ class DataBloc {
Stream<String> get data => _dataController.stream;
final StreamController<String> _dataController = StreamController.broadcast();
final String param;
DataBloc(this._dataRepository, this.param);
DataBloc(this._dataRepository);
Future<void> fetchData() async {
try {
_dataController.sink.add(await _dataRepository.getData(param));
_dataController.sink.add(await _dataRepository.getData());
} catch (e) {
_dataController.sink.addError(e);
}
@@ -78,7 +76,7 @@ class DataBloc {
}
abstract class DataRepository {
Future<String> getData(String param);
Future<String> getData();
}
class NetworkDataRepository implements DataRepository {
@@ -88,42 +86,26 @@ class NetworkDataRepository implements DataRepository {
NetworkDataRepository(this._apiClient);
@override
Future<String> getData(String param) async => await _apiClient.sendRequest(
url: 'www.google.com',
token: _token,
requestBody: {'type': 'data'},
param: param);
Future<String> getData() async => await _apiClient.sendRequest(
url: 'www.google.com', token: _token, requestBody: {'type': 'data'});
}
abstract class ApiClient {
Future sendRequest({
@required String url,
String token,
Map requestBody,
String param,
});
Future sendRequest({@required String url, String token, Map requestBody});
}
class ApiClientMock implements ApiClient {
@override
Future sendRequest({
@required String? url,
String? token,
Map? requestBody,
String? param,
}) async {
return 'Local Data $param';
Future sendRequest(
{@required String? url, String? token, Map? requestBody}) async {
return 'Local Data';
}
}
class ApiClientImpl implements ApiClient {
@override
Future sendRequest({
@required String? url,
String? token,
Map? requestBody,
String? param,
}) async {
return 'Network data $param';
Future sendRequest(
{@required String? url, String? token, Map? requestBody}) async {
return 'Network data';
}
}

View File

@@ -1,17 +1,17 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
library;
library cherrypick;
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
export 'package:cherrypick/src/binding.dart';
export 'package:cherrypick/src/helper.dart';

View File

@@ -1,20 +1,24 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
enum Mode { simple, instance, providerInstance, providerInstanceWithParams }
typedef ProviderWithParams<T> = T Function(dynamic params);
typedef AsyncProvider<T> = Future<T> Function();
typedef AsyncProviderWithParams<T> = Future<T> Function(dynamic params);
/// RU: Класс Binding<T> настраивает параметры экземпляра.
/// ENG: The Binding<T> class configures the settings for the instance.
///
@@ -24,6 +28,9 @@ class Binding<T> {
late String _name;
T? _instance;
T? Function()? _provider;
AsyncProvider<T>? asyncProvider;
AsyncProviderWithParams<T>? asyncProviderWithParams;
ProviderWithParams<T>? _providerWithParams;
late bool _isSingleton = false;
late bool _isNamed = false;
@@ -94,6 +101,16 @@ class Binding<T> {
return this;
}
/// RU: Инициализация экземляпяра  через провайдер [value].
/// ENG: Initialization instance via provider [value].
///
/// return [Binding]
Binding<T> toProvideAsync(AsyncProvider<T> provider) {
_mode = Mode.providerInstance;
asyncProvider = provider;
return this;
}
/// RU: Инициализация экземляпяра  через провайдер [value] c динамическим параметром.
/// ENG: Initialization instance via provider [value] with a dynamic param.
///
@@ -104,6 +121,16 @@ class Binding<T> {
return this;
}
/// RU: Инициализация экземляра через асинхронный провайдер [value] с динамическим параметром.
/// ENG: Initializes the instance via async provider [value] with a dynamic param.
///
/// return [Binding]
Binding<T> toProvideAsyncWithParams(AsyncProviderWithParams<T> provider) {
_mode = Mode.providerInstanceWithParams;
asyncProviderWithParams = provider;
return this;
}
/// RU: Инициализация экземляпяра  как сингелтон [value].
/// ENG: Initialization instance as a singelton [value].
///

View File

@@ -1,15 +1,15 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'package:cherrypick/src/scope.dart';
abstract class Factory<T> {

View File

@@ -1,15 +1,15 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'package:cherrypick/src/scope.dart';
import 'package:meta/meta.dart';

View File

@@ -1,15 +1,15 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'dart:collection';
import 'package:cherrypick/src/binding.dart';

View File

@@ -1,15 +1,15 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import 'dart:collection';
import 'package:cherrypick/src/binding.dart';
@@ -130,6 +130,47 @@ class Scope {
}
// 2 Поиск зависимостей в родительском скоупе
return _parentScope?.tryResolve(named: named);
return _parentScope?.tryResolve(named: named, params: params);
}
/// RU: Асинхронно возвращает найденную зависимость, определенную параметром типа [T].
/// Выдает [StateError], если зависимость не может быть разрешена.
/// Если хотите получить [null], если зависимость не может быть найдена, используйте [tryResolveAsync].
/// return - возвращает объект типа [T] or [StateError]
///
/// ENG: Asynchronously returns the found dependency specified by the type parameter [T].
/// Throws [StateError] if the dependency cannot be resolved.
/// If you want to get [null] if the dependency cannot be found, use [tryResolveAsync] instead.
/// return - returns an object of type [T] or [StateError]
///
Future<T> resolveAsync<T>({String? named, dynamic params}) async {
var resolved = await tryResolveAsync<T>(named: named, params: params);
if (resolved != null) {
return resolved;
} else {
throw StateError(
'Can\'t resolve async dependency `$T`. Maybe you forget register it?');
}
}
Future<T?> tryResolveAsync<T>({String? named, dynamic params}) async {
if (_modulesList.isNotEmpty) {
for (var module in _modulesList) {
for (var binding in module.bindingSet) {
if (binding.key == T &&
((!binding.isNamed && named == null) ||
(binding.isNamed && named == binding.name))) {
if (binding.asyncProvider != null) {
return await binding.asyncProvider?.call();
}
if (binding.asyncProviderWithParams != null) {
return await binding.asyncProviderWithParams!(params);
}
}
}
}
}
return _parentScope?.tryResolveAsync(named: named, params: params);
}
}

View File

@@ -1,6 +1,6 @@
name: cherrypick
description: Cherrypick is a small dependency injection (DI) library for dart/flutter projects.
version: 2.0.1
version: 2.1.0
homepage: https://pese-git.github.io/cherrypick-site/
documentation: https://github.com/pese-git/cherrypick/wiki
repository: https://github.com/pese-git/cherrypick
@@ -13,9 +13,8 @@ dependencies:
meta: ^1.3.0
dev_dependencies:
#pedantic: ^1.11.0
test: ^1.17.2
lints: ^5.0.0
test: ^1.25.15
mockito: ^5.0.6
lints: ^2.1.0
melos: ^6.3.2

View File

@@ -188,6 +188,25 @@ void main() {
});
});
group('Check Async provider.', () {
test('Binding resolves value asynchronously', () async {
final expectedValue = 5;
final binding = Binding<int>().toProvideAsync(() async => expectedValue);
final result = await binding.asyncProvider?.call();
expect(result, expectedValue);
});
test('Binding resolves value asynchronously with params', () async {
final expectedValue = 5;
final binding = Binding<int>().toProvideAsyncWithParams(
(param) async => expectedValue + (param as int));
final result = await binding.asyncProviderWithParams?.call(3);
expect(result, expectedValue + 3);
});
});
group('Check singleton provide.', () {
group('Without name.', () {
test('Binding resolves null', () {

View File

@@ -1,3 +1,15 @@
## 1.1.1
- Graduate package to a stable release. See pre-releases prior to this version for changelog entries.
## 1.1.1-dev.1
- **FIX**: fix warnings.
## 1.1.1-dev.0
- Update a dependency to the latest release.
## 1.1.0
- **FIX**: update description.

View File

@@ -1,6 +1,6 @@
# CherryPick Flutter
`cherrypick_flutter` is a Flutter library that allows access to the root scope through the context using `CherryPickProvider`. This package is designed to provide a simple and convenient way to interact with the root scope within the widget tree.
`cherrypick_flutter` offers a Flutter integration to access and manage dependency injection scopes using the `CherryPickProvider`. This setup facilitates accessing the root scope directly from the widget tree, providing a straightforward mechanism for dependences management within Flutter applications.
## Installation
@@ -11,13 +11,13 @@ dependencies:
cherrypick_flutter: ^1.0.0
```
Then run `flutter pub get` to install the package.
Run `flutter pub get` to install the package dependencies.
## Usage
### Importing the Package
To start using `cherrypick_flutter`, import it into your Dart code:
To begin using `cherrypick_flutter`, import it within your Dart file:
```dart
import 'package:cherrypick_flutter/cherrypick_flutter.dart';
@@ -25,7 +25,7 @@ import 'package:cherrypick_flutter/cherrypick_flutter.dart';
### Providing State with `CherryPickProvider`
Use `CherryPickProvider` to wrap the part of the widget tree that requires access to the provided state.
Use `CherryPickProvider` to encase the widget tree section that requires access to the root or specific subscopes:
```dart
import 'package:flutter/material.dart';
@@ -34,35 +34,40 @@ import 'package:cherrypick_flutter/cherrypick_flutter.dart';
void main() {
runApp(
CherryPickProvider(
rootScope: yourRootScopeInstance,
child: MyApp(),
),
);
}
```
Note: The current implementation of `CherryPickProvider` does not directly pass a `rootScope`. Instead, it utilizes its methods to open root and sub-scopes internally.
### Accessing State
To access the state provided by `CherryPickProvider`, use the `of` method. This is typically done in the `build` method of your widgets.
Access the state provided by `CherryPickProvider` within widget `build` methods using the `of` method:
```dart
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final rootScope = CherryPickProvider.of(context).rootScope;
final CherryPickProvider cherryPick = CherryPickProvider.of(context);
final rootScope = cherryPick.openRootScope();
return Text('Current state: ${rootScope.someStateValue}');
// Use the rootScope or open a subScope as needed
final subScope = cherryPick.openSubScope(scopeName: "exampleScope");
return Text('Scope accessed!');
}
}
```
### Updating State
The `CherryPickProvider` will automatically update its dependents when its state changes. Ensure to override the `updateShouldNotify` method to specify when notifications should occur, as shown in the provided implementation.
The `CherryPickProvider` setup internally manages state updates. Ensure the `updateShouldNotify` method accurately reflects when the dependents should receive updates. In the provided implementation, it currently does not notify updates automatically.
## Example
Here is a simple example showing how to implement and use the `CherryPickProvider`.
Here is an example illustrating how to implement and utilize `CherryPickProvider` within a Flutter application:
```dart
class MyApp extends StatelessWidget {
@@ -70,7 +75,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final rootScope = CherryPickProvider.of(context).rootScope;
final rootScope = CherryPickProvider.of(context).openRootScope();
return MaterialApp.router(
routerDelegate: rootScope.resolve<AppRouter>().delegate(),
@@ -81,10 +86,12 @@ class MyApp extends StatelessWidget {
}
```
In this example, `CherryPickProvider` accesses and resolves dependencies using root scope and potentially sub-scopes configured by the application.
## Contributing
We welcome contributions from the community. Please open issues and pull requests if you have ideas for improvements.
Contributions to improve this library are welcome. Feel free to open issues and submit pull requests on the repository.
## License
This project is licensed under the Apache License 2.0.
This project is licensed under the Apache License 2.0. A copy of the license can be obtained at [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).

View File

@@ -1,15 +1,15 @@
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
/// http://www.apache.org/licenses/LICENSE-2.0
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
library cherrypick_flutter;
library;
//
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
export 'src/cherrypick_provider.dart';

View File

@@ -2,7 +2,7 @@ import 'package:cherrypick/cherrypick.dart';
import 'package:flutter/widgets.dart';
///
/// Copyright 2021 Sergey Penkovsky <sergey.penkovsky@gmail.com>
/// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at

View File

@@ -1,6 +1,6 @@
name: cherrypick_flutter
description: "Flutter library that allows access to the root scope through the context using `CherryPickProvider`."
version: 1.1.0
version: 1.1.1
homepage: https://pese-git.github.io/cherrypick-site/
documentation: https://github.com/pese-git/cherrypick/wiki
repository: https://github.com/pese-git/cherrypick
@@ -13,12 +13,14 @@ environment:
dependencies:
flutter:
sdk: flutter
cherrypick: ^2.0.0
cherrypick: ^2.1.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^4.0.0
flutter_lints: ^5.0.0
test: ^1.25.7
melos: ^6.3.2
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

52
examples/client_app/.gitignore vendored Normal file
View File

@@ -0,0 +1,52 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
pubspec_overrides.yaml
**/*.g.dart
**/*.gr.dart
**/*.freezed.dart

View File

@@ -0,0 +1,30 @@
# 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: "4cf269e36de2573851eaef3c763994f8f9be494d"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
- platform: web
create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@@ -0,0 +1,16 @@
# client_app
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View File

@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@@ -0,0 +1,41 @@
import 'package:cherrypick/cherrypick.dart';
import 'package:flutter/material.dart';
import 'package:cherrypick_flutter/cherrypick_flutter.dart';
import 'my_home_page.dart';
import 'use_case.dart';
void main() {
// Здесь происходит инициализация рутового скоупа и привязка зависимостей
CherryPick.openRootScope().installModules([
// Создаем модуль, который будет предоставлять UseCase
ModuleWithUseCase(),
]);
runApp(
const CherryPickProvider(
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example App',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MyHomePage(),
);
}
}
// Модуль для настройки зависимостей
class ModuleWithUseCase extends Module {
@override
void builder(Scope currentScope) {
// Привязка UseCase как singleton
bind<UseCase>().toInstance(UseCase());
}
}

View File

@@ -0,0 +1,23 @@
import 'package:flutter/material.dart';
import 'package:cherrypick_flutter/cherrypick_flutter.dart';
import 'use_case.dart';
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
// Разрешение зависимости UseCase из рутового скоупа
final UseCase useCase =
CherryPickProvider.of(context).openRootScope().resolve<UseCase>();
return Scaffold(
appBar: AppBar(
title: const Text('Example App'),
),
body: Center(
child: Text(useCase.fetchData()),
),
);
}
}

View File

@@ -0,0 +1,3 @@
class UseCase {
String fetchData() => "Data fetched by UseCase";
}

View File

@@ -0,0 +1,229 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
cherrypick:
dependency: "direct main"
description:
name: cherrypick
sha256: e1e2b4f3a70cbe7760e479e6ddb7dce2fc85a1bbb2fba6c398efe235ed111dfe
url: "https://pub.dev"
source: hosted
version: "2.0.2"
cherrypick_flutter:
dependency: "direct main"
description:
name: cherrypick_flutter
sha256: ad63ae816b7d1147ffb0a82bcae5a1ea3d51e9d398a79459c619464391a43a79
url: "https://pub.dev"
source: hosted
version: "1.1.1"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.dev"
source: hosted
version: "1.0.8"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.15.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "14.2.5"
sdks:
dart: ">=3.5.2 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"

View File

@@ -0,0 +1,65 @@
name: client_app
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ^3.5.2
dependencies:
flutter:
sdk: flutter
cherrypick: ^2.1.0
cherrypick_flutter: ^1.1.1
cupertino_icons: ^1.0.8
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^4.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/to/resolution-aware-images
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/to/asset-from-package
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/to/font-from-package

View File

@@ -0,0 +1,31 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
//import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
//import 'package:client_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
expect(1, 1);
// Build our app and trigger a frame.
//await tester.pumpWidget(const MyApp());
//// Verify that our counter starts at 0.
//expect(find.text('0'), findsOneWidget);
//expect(find.text('1'), findsNothing);
//// Tap the '+' icon and trigger a frame.
//await tester.tap(find.byIcon(Icons.add));
//await tester.pump();
//// Verify that our counter has incremented.
//expect(find.text('0'), findsNothing);
//expect(find.text('1'), findsOneWidget);
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="client_app">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>client_app</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>

View File

@@ -0,0 +1,35 @@
{
"name": "client_app",
"short_name": "client_app",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}

48
examples/postly/.gitignore vendored Normal file
View File

@@ -0,0 +1,48 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# 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/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
**/*.g.dart
**/*.gr.dart
**/*.freezed.dart

30
examples/postly/.metadata Normal file
View File

@@ -0,0 +1,30 @@
# 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: "4cf269e36de2573851eaef3c763994f8f9be494d"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
- platform: web
create_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
base_revision: 4cf269e36de2573851eaef3c763994f8f9be494d
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

16
examples/postly/README.md Normal file
View File

@@ -0,0 +1,16 @@
# postly
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View File

@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

View File

@@ -0,0 +1,16 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'post_model.freezed.dart';
part 'post_model.g.dart';
@freezed
class PostModel with _$PostModel {
const factory PostModel({
required int id,
required String title,
required String body,
}) = _PostModel;
factory PostModel.fromJson(Map<String, dynamic> json) =>
_$PostModelFromJson(json);
}

View File

@@ -0,0 +1,17 @@
import 'package:retrofit/retrofit.dart';
import 'package:dio/dio.dart';
import '../model/post_model.dart';
part 'json_placeholder_api.g.dart';
@RestApi(baseUrl: 'https://jsonplaceholder.typicode.com/')
abstract class JsonPlaceholderApi {
factory JsonPlaceholderApi(Dio dio, {String baseUrl}) = _JsonPlaceholderApi;
@GET('/posts')
Future<List<PostModel>> getPosts();
@GET('/posts/{id}')
Future<PostModel> getPost(@Path('id') int id);
}

View File

@@ -0,0 +1,32 @@
import 'package:dartz/dartz.dart';
import '../domain/entity/post.dart';
import '../domain/repository/post_repository.dart';
import 'network/json_placeholder_api.dart';
class PostRepositoryImpl implements PostRepository {
final JsonPlaceholderApi api;
PostRepositoryImpl(this.api);
@override
Future<Either<Exception, List<Post>>> getPosts() async {
try {
final posts = await api.getPosts();
return Right(posts
.map((e) => Post(id: e.id, title: e.title, body: e.body))
.toList());
} catch (e) {
return Left(Exception(e.toString()));
}
}
@override
Future<Either<Exception, Post>> getPost(int id) async {
try {
final post = await api.getPost(id);
return Right(Post(id: post.id, title: post.title, body: post.body));
} catch (e) {
return Left(Exception(e.toString()));
}
}
}

View File

@@ -0,0 +1,21 @@
import 'package:dio/dio.dart';
import 'package:cherrypick/cherrypick.dart';
import '../data/network/json_placeholder_api.dart';
import '../data/post_repository_impl.dart';
import '../domain/repository/post_repository.dart';
class AppModule extends Module {
@override
void builder(Scope currentScope) {
bind<Dio>().toProvide(() => Dio()).singleton();
bind<JsonPlaceholderApi>()
.toProvide(() => JsonPlaceholderApi(currentScope.resolve<Dio>()))
.singleton();
bind<PostRepository>()
.toProvide(() =>
PostRepositoryImpl(currentScope.resolve<JsonPlaceholderApi>()))
.singleton();
}
}

View File

@@ -0,0 +1,12 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'post.freezed.dart';
@freezed
class Post with _$Post {
const factory Post({
required int id,
required String title,
required String body,
}) = _Post;
}

View File

@@ -0,0 +1,7 @@
import 'package:dartz/dartz.dart';
import '../entity/post.dart';
abstract class PostRepository {
Future<Either<Exception, List<Post>>> getPosts();
Future<Either<Exception, Post>> getPost(int id);
}

View File

@@ -0,0 +1,36 @@
import 'package:cherrypick/cherrypick.dart';
import 'package:flutter/material.dart';
import 'di/app_module.dart';
import 'domain/repository/post_repository.dart';
import 'presentation/bloc/post_bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'router/app_router.dart';
void main() {
final scope = CherryPick.openRootScope();
scope.installModules([AppModule()]);
runApp(MyApp(scope: scope));
}
class MyApp extends StatelessWidget {
final Scope scope;
final _appRouter = AppRouter();
MyApp({super.key, required this.scope});
@override
Widget build(BuildContext context) {
// Получаем репозиторий через injector
final repository = scope.resolve<PostRepository>();
return BlocProvider(
create: (_) => PostBloc(repository),
child: MaterialApp.router(
routeInformationParser: _appRouter.defaultRouteParser(),
routerDelegate: _appRouter.delegate(),
theme: ThemeData.light(),
),
);
}
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../domain/entity/post.dart';
import '../../domain/repository/post_repository.dart';
part 'post_bloc.freezed.dart';
@freezed
class PostEvent with _$PostEvent {
const factory PostEvent.fetchAll() = _FetchAll;
}
@freezed
class PostState with _$PostState {
const factory PostState.initial() = _Initial;
const factory PostState.loading() = _Loading;
const factory PostState.loaded(List<Post> posts) = _Loaded;
const factory PostState.failure(String message) = _Failure;
}
class PostBloc extends Bloc<PostEvent, PostState> {
final PostRepository repository;
PostBloc(this.repository) : super(const PostState.initial()) {
on<PostEvent>((event, emit) async {
await event.map(
fetchAll: (e) async {
emit(const PostState.loading());
final result = await repository.getPosts();
result.fold(
(l) => emit(PostState.failure(l.toString())),
(r) => emit(PostState.loaded(r)),
);
},
);
});
}
}

View File

@@ -0,0 +1,21 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import '../../domain/entity/post.dart';
@RoutePage()
class PostDetailsPage extends StatelessWidget {
final Post post;
const PostDetailsPage({super.key, required this.post});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Post #${post.id}')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(post.body),
),
);
}
}

View File

@@ -0,0 +1,42 @@
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../router/app_router.gr.dart';
import '../bloc/post_bloc.dart';
@RoutePage()
class PostsPage extends StatelessWidget {
const PostsPage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) =>
context.read<PostBloc>()..add(const PostEvent.fetchAll()),
child: Scaffold(
appBar: AppBar(title: const Text('Posts')),
body: BlocBuilder<PostBloc, PostState>(
builder: (context, state) {
return state.when(
initial: () => const SizedBox.shrink(),
loading: () => const Center(child: CircularProgressIndicator()),
loaded: (posts) => ListView.builder(
itemCount: posts.length,
itemBuilder: (ctx, i) => ListTile(
title: Text(posts[i].title),
subtitle: Text(posts[i].body),
onTap: () {
AutoRouter.of(context)
.push(PostDetailsRoute(post: posts[i]));
},
),
),
failure: (msg) => Center(child: Text('Error: $msg')),
);
},
),
),
);
}
}

View File

@@ -0,0 +1,12 @@
import 'package:auto_route/auto_route.dart';
import 'app_router.gr.dart';
@AutoRouterConfig()
class AppRouter extends $AppRouter {
@override
List<AutoRoute> get routes => [
AutoRoute(page: PostsRoute.page, initial: true),
AutoRoute(page: PostDetailsRoute.page),
];
}

View File

@@ -0,0 +1,730 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
url: "https://pub.dev"
source: hosted
version: "72.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.2"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
url: "https://pub.dev"
source: hosted
version: "6.7.0"
args:
dependency: transitive
description:
name: args
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
url: "https://pub.dev"
source: hosted
version: "2.7.0"
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
auto_route:
dependency: "direct main"
description:
name: auto_route
sha256: eb33554581a0a4aa7e6da0f13a44291a55bf71359012f1d9feb41634ff908ff8
url: "https://pub.dev"
source: hosted
version: "7.9.2"
auto_route_generator:
dependency: "direct dev"
description:
name: auto_route_generator
sha256: "11067a3bcd643812518fe26c0c9ec073990286cabfd9d74b6da9ef9b913c4d22"
url: "https://pub.dev"
source: hosted
version: "7.3.2"
bloc:
dependency: transitive
description:
name: bloc
sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
url: "https://pub.dev"
source: hosted
version: "8.1.4"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
build:
dependency: transitive
description:
name: build
sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
build_config:
dependency: transitive
description:
name: build_config
sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
url: "https://pub.dev"
source: hosted
version: "1.1.1"
build_daemon:
dependency: transitive
description:
name: build_daemon
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
build_runner:
dependency: "direct dev"
description:
name: build_runner
sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
url: "https://pub.dev"
source: hosted
version: "2.4.13"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
url: "https://pub.dev"
source: hosted
version: "7.3.2"
built_collection:
dependency: transitive
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
url: "https://pub.dev"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4
url: "https://pub.dev"
source: hosted
version: "8.9.5"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cherrypick:
dependency: "direct main"
description:
name: cherrypick
sha256: e1e2b4f3a70cbe7760e479e6ddb7dce2fc85a1bbb2fba6c398efe235ed111dfe
url: "https://pub.dev"
source: hosted
version: "2.0.2"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
code_builder:
dependency: transitive
description:
name: code_builder
sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
url: "https://pub.dev"
source: hosted
version: "4.10.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
convert:
dependency: transitive
description:
name: convert
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
url: "https://pub.dev"
source: hosted
version: "3.1.2"
crypto:
dependency: transitive
description:
name: crypto
sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
url: "https://pub.dev"
source: hosted
version: "3.0.6"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.dev"
source: hosted
version: "1.0.8"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
url: "https://pub.dev"
source: hosted
version: "2.3.7"
dartz:
dependency: "direct main"
description:
name: dartz
sha256: e6acf34ad2e31b1eb00948692468c30ab48ac8250e0f0df661e29f12dd252168
url: "https://pub.dev"
source: hosted
version: "0.10.1"
dio:
dependency: "direct main"
description:
name: dio
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
url: "https://pub.dev"
source: hosted
version: "5.8.0+1"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
file:
dependency: transitive
description:
name: file
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
url: "https://pub.dev"
source: hosted
version: "7.0.1"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
url: "https://pub.dev"
source: hosted
version: "1.1.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_bloc:
dependency: "direct main"
description:
name: flutter_bloc
sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
url: "https://pub.dev"
source: hosted
version: "8.1.6"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
freezed:
dependency: "direct dev"
description:
name: freezed
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e"
url: "https://pub.dev"
source: hosted
version: "2.5.7"
freezed_annotation:
dependency: "direct main"
description:
name: freezed_annotation
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
url: "https://pub.dev"
source: hosted
version: "2.4.4"
frontend_server_client:
dependency: transitive
description:
name: frontend_server_client
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
url: "https://pub.dev"
source: hosted
version: "4.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
url: "https://pub.dev"
source: hosted
version: "2.1.3"
graphs:
dependency: transitive
description:
name: graphs
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
url: "https://pub.dev"
source: hosted
version: "3.2.2"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
io:
dependency: transitive
description:
name: io
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
url: "https://pub.dev"
source: hosted
version: "1.0.5"
js:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.7.1"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c
url: "https://pub.dev"
source: hosted
version: "6.9.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
macros:
dependency: transitive
description:
name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
url: "https://pub.dev"
source: hosted
version: "0.1.2-main.4"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.15.0"
mime:
dependency: transitive
description:
name: mime
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
nested:
dependency: transitive
description:
name: nested
sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
package_config:
dependency: transitive
description:
name: package_config
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
url: "https://pub.dev"
source: hosted
version: "2.2.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "6.0.2"
pool:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
url: "https://pub.dev"
source: hosted
version: "1.5.1"
protobuf:
dependency: transitive
description:
name: protobuf
sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
provider:
dependency: transitive
description:
name: provider
sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84"
url: "https://pub.dev"
source: hosted
version: "6.1.5"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: "81876843eb50dc2e1e5b151792c9a985c5ed2536914115ed04e9c8528f6647b0"
url: "https://pub.dev"
source: hosted
version: "1.4.0"
retrofit:
dependency: "direct main"
description:
name: retrofit
sha256: c6cc9ad3374e6d07008343140a67afffaaa34cdf6bf08d4847d91417a99dcf45
url: "https://pub.dev"
source: hosted
version: "4.4.2"
retrofit_generator:
dependency: "direct dev"
description:
name: retrofit_generator
sha256: "8dfc406cdfa171f33cbd21bf5bd8b6763548cc217de19cdeaa07a76727fac4ca"
url: "https://pub.dev"
source: hosted
version: "8.2.1"
shelf:
dependency: transitive
description:
name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
url: "https://pub.dev"
source: hosted
version: "1.4.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
url: "https://pub.dev"
source: hosted
version: "2.0.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
source_helper:
dependency: transitive
description:
name: source_helper
sha256: "86d247119aedce8e63f4751bd9626fc9613255935558447569ad42f9f5b48b3c"
url: "https://pub.dev"
source: hosted
version: "1.3.5"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
url: "https://pub.dev"
source: hosted
version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
timing:
dependency: transitive
description:
name: timing
sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.dev"
source: hosted
version: "1.4.0"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "14.2.5"
watcher:
dependency: transitive
description:
name: watcher
sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
web:
dependency: transitive
description:
name: web
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.dev"
source: hosted
version: "1.1.1"
web_socket:
dependency: transitive
description:
name: web_socket
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
url: "https://pub.dev"
source: hosted
version: "3.0.3"
xml:
dependency: transitive
description:
name: xml
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.5.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev"
source: hosted
version: "3.1.3"
sdks:
dart: ">=3.5.2 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"

View File

@@ -0,0 +1,40 @@
name: postly
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ^3.5.2
dependencies:
flutter:
sdk: flutter
cherrypick: ^2.1.0
dio: ^5.4.0
retrofit: ^4.0.3
freezed_annotation: ^2.0.0
dartz: ^0.10.1
flutter_bloc: ^8.1.2
auto_route: ^7.8.4
cupertino_icons: ^1.0.8
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^4.0.0
build_runner: ^2.4.6
retrofit_generator: ^8.0.4
freezed: ^2.3.2
json_serializable: any
auto_route_generator: ^7.3.2
flutter:
uses-material-design: true

View File

@@ -0,0 +1,41 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:cherrypick/cherrypick.dart';
//import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:postly/di/app_module.dart';
//import 'package:postly/main.dart';
void main() {
late Scope scope;
setUp(() {
scope = CherryPick.openRootScope();
scope.installModules([AppModule()]);
});
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
expect(1, 1);
// Build our app and trigger a frame.
//await tester.pumpWidget(MyApp(
// scope: scope,
//));
//// Verify that our counter starts at 0.
//expect(find.text('0'), findsOneWidget);
//expect(find.text('1'), findsNothing);
//// Tap the '+' icon and trigger a frame.
//await tester.tap(find.byIcon(Icons.add));
//await tester.pump();
//// Verify that our counter has incremented.
//expect(find.text('0'), findsNothing);
//expect(find.text('1'), findsOneWidget);
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="postly">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>postly</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>

View File

@@ -0,0 +1,35 @@
{
"name": "postly",
"short_name": "postly",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}

View File

@@ -5,11 +5,20 @@ sdkPath: .fvm/flutter_sdk
packages:
- cherrypick
- cherrypick_flutter
- examples/client_app
- examples/postly
scripts:
analyze:
run: |
flutter analyze
exec: dart analyze
format:
exec: dart format
test:
exec: flutter test
codegen:
run: |
flutter format
melos exec --scope="postly" -- dart run build_runner build --delete-conflicting-outputs