diff --git a/README.md b/README.md index 1ca608f..5a0c194 100644 --- a/README.md +++ b/README.md @@ -5,38 +5,42 @@ It contains the source code for Aurora Flutter's packages (i.e., packages develo ## Package done -Packages made or for review +Package verified -| Package | Version | OS Version | State | Comment | -|---------------------------------------------------------------------------------------|---------|------------|---------|---------------------------------------------------------------------| -| [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) | 5.4.1 | 4.0.2 | Review | Дополнительная фича с получением высоты клавиатуры | -| [battery_plus](https://pub.dev/packages/battery_plus) | 4.0.1 | 4.0.2 | Review | - | -| [device_info_plus](https://pub.dev/packages/device_info_plus) | 8.2.2 | 4.0.2 | Review | - | -| [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) | 14.1.1 | 4.0.2 | Review | - | -| [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) | 8.0.0 | 4.0.2 | Review | Ключь нужно генерировать сейчас самому, например через пин от юзера | -| [package_info_plus](https://pub.dev/packages/package_info_plus) | 3.1.2 | 4.0.2 | Review | Достать `version` & `build_number` не удалось | -| [path_provider](https://pub.dev/packages/path_provider) | 2.0.15 | 4.0.2 | Review | - | -| [shared_preferences](https://pub.dev/packages/shared_preferences) | 2.1.2 | 4.0.2 | Review | - | -| [sqflite](https://pub.dev/packages/sqflite) | 2.2.6 | 4.0.2 | Review | - | -| [wakelock](https://pub.dev/packages/wakelock) | 0.6.2 | 4.0.2 | Review | - | -| xdga_directories | 0.0.1 | 4.0.2 | Review | Аналог [xdg_directories](https://pub.dev/packages/xdg_directories) | - -## Package verified - -Verified packages on Aurora OS - -| Package | Version | OS Version | State | Comment | -|-------------------------------------------------------------------------|---------|-------------|--------|------------------------------------| -| [flutter_cache_manager](https://pub.dev/packages/flutter_cache_manager) | 3.3.0 | 4.0.2 | Done | Depends on `path_provider` | -| [cached_network_image](https://pub.dev/packages/cached_network_image) | 3.2.3 | 4.0.2 | Done | Depends on `flutter_cache_manager` | -| [crypto](https://pub.dev/packages/crypto) | 3.0.2 | 4.0.2 | Done | - | -| [cupertino_icons](https://pub.dev/packages/cupertino_icons) | 1.0.5 | 4.0.2 | Done | - | -| [get_it](https://pub.dev/packages/get_it) | 7.6.0 | 4.0.2 | Done | - | -| [google_fonts](https://pub.dev/packages/google_fonts) | 4.0.4 | 4.0.2 | Done | - | -| [intl](https://pub.dev/packages/intl) | 0.17.0 | 4.0.2 | Done | - | -| [photo_view](https://pub.dev/packages/photo_view) | 0.14.0 | 4.0.2 | Done | - | -| [scoped_model](https://pub.dev/packages/scoped_model) | 2.0.0 | 4.0.2 | Done | - | -| [universal_io](https://pub.dev/packages/universal_io) | 2.2.0 | 4.0.2 | Done | - | +| Package | Version | OS Version | Comment | +|-------------------------------------------------------------------------------------|-----------|------------|---------------------------------------------------------------------| +| [flutter_keyboard_visibility](https://pub.dev/packages/flutter_keyboard_visibility) | 5.4.1 | 4.0.2 | Дополнительная фича с получением высоты клавиатуры | +| [battery_plus](https://pub.dev/packages/battery_plus) | 4.0.1 | 4.0.2 | - | +| [device_info_plus](https://pub.dev/packages/device_info_plus) | 8.2.2 | 4.0.2 | - | +| [flutter_local_notifications](https://pub.dev/packages/flutter_local_notifications) | 14.1.1 | 4.0.2 | - | +| [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) | 8.0.0 | 4.0.2 | Ключь нужно генерировать сейчас самому, например через пин от юзера | +| [package_info_plus](https://pub.dev/packages/package_info_plus) | 3.1.2 | 4.0.2 | Достать `version` & `build_number` не удалось | +| [path_provider](https://pub.dev/packages/path_provider) | 2.0.15 | 4.0.2 | - | +| [shared_preferences](https://pub.dev/packages/shared_preferences) | 2.1.2 | 4.0.2 | - | +| [sqflite](https://pub.dev/packages/sqflite) | 2.2.6 | 4.0.2 | - | +| [wakelock](https://pub.dev/packages/wakelock) | 0.6.2 | 4.0.2 | - | +| xdga_directories | 0.0.1 | 4.0.2 | Аналог [xdg_directories](https://pub.dev/packages/xdg_directories) | +| [flutter_cache_manager](https://pub.dev/packages/flutter_cache_manager) | 3.3.0 | 4.0.2 | Depends on `path_provider` | +| [cached_network_image](https://pub.dev/packages/cached_network_image) | 3.2.3 | 4.0.2 | Depends on `flutter_cache_manager` | +| [crypto](https://pub.dev/packages/crypto) | 3.0.2 | 4.0.2 | - | +| [cupertino_icons](https://pub.dev/packages/cupertino_icons) | 1.0.5 | 4.0.2 | - | +| [get_it](https://pub.dev/packages/get_it) | 7.6.0 | 4.0.2 | - | +| [google_fonts](https://pub.dev/packages/google_fonts) | 4.0.4 | 4.0.2 | - | +| [intl](https://pub.dev/packages/intl) | 0.17.0 | 4.0.2 | - | +| [photo_view](https://pub.dev/packages/photo_view) | 0.14.0 | 4.0.2 | - | +| [scoped_model](https://pub.dev/packages/scoped_model) | 2.0.0 | 4.0.2 | - | +| [dartz](https://pub.dev/packages/dartz) | 0.10.1 | 4.0.2 | - | +| [freezed](https://pub.dev/packages/freezed) | 2.3.3 | 4.0.2 | - | +| [equatable](https://pub.dev/packages/equatable) | 2.0.5 | 4.0.2 | - | +| [flutter_markdown](https://pub.dev/packages/flutter_markdown) | 0.6.15 | 4.0.2 | - | +| [build_runner](https://pub.dev/packages/build_runner) | 2.3.3 | 4.0.2 | - | +| [freezed_annotation](https://pub.dev/packages/freezed_annotation) | 2.2.0 | 4.0.2 | - | +| [json_annotation](https://pub.dev/packages/json_annotation) | 4.8.0 | 4.0.2 | - | +| [json_serializable](https://pub.dev/packages/json_serializable) | 6.6.1 | 4.0.2 | - | +| [provider](https://pub.dev/packages/provider) | 6.0.5 | 4.0.2 | - | +| [qr_flutter](https://pub.dev/packages/qr_flutter) | 4.0.0 | 4.0.2 | - | +| [rxdart](https://pub.dev/packages/rxdart) | 0.27.7 | 4.0.2 | - | +| [translator](https://pub.dev/packages/translator) | 0.1.7 | 4.0.2 | - | ## Package in progress diff --git a/example/.gitignore b/example/.gitignore index 3db3823..bf6a5bc 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -45,3 +45,7 @@ app.*.map.json # Aurora generated /aurora/flutter + +# Dart generated +*.g.dart +*.freezed.dart diff --git a/example/lib/app.dart b/example/lib/app.dart index 2549886..180e1bb 100644 --- a/example/lib/app.dart +++ b/example/lib/app.dart @@ -26,6 +26,7 @@ class MyApp extends StatelessWidget { ); } } + return MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, diff --git a/example/lib/l10n/app_en.arb b/example/lib/l10n/app_en.arb index ee8f10c..2647a5f 100644 --- a/example/lib/l10n/app_en.arb +++ b/example/lib/l10n/app_en.arb @@ -1,4 +1,37 @@ { + "@_PROVIDER": {}, + "providerTitle": "Provider", + "providerSubtitle": "Simple example use provider package", + + "@_RXDART": {}, + "rxdartTitle": "Rxdart", + "rxdartSubtitle": "Simple example using Rx for Dart", + + "@_TRANSLATOR": {}, + "translatorTitle": "Translate", + "translatorSubtitle": "Translate en -> ru 'Hello!'", + "translatorText": "Hello!", + + "@_EQUATABLE": {}, + "equatableTitleDefault": "It's default class, 46 of lines", + "equatableTitleFreezed": "It's equatable class, 26 of lines", + "equatableSubtitle": "Methods: toString, operator ==, hashCode.", + + "@_FREEZED": {}, + "freezedTitleDefault": "It's default class, 74 of lines", + "freezedTitleFreezed": "It's freezed class, 21 of lines", + "freezedSubtitle": "Methods: fromJson, copyWith, toJson, toString, operator ==, hashCode.", + + "@_DARTZ": {}, + "dartzTitle": "Convert size", + "dartzDesc": "Convert the size grid of Russia to the size grid of Europe.", + "dartzErrorReq": "Required field", + "dartzErrorInt": "Please enter RUS size (42 - 62)", + "dartzErrorFound": "Size not found (42 - 62)", + "dartzDefaultValue": "Specify the size and click 'Submit'", + "dartzLabel": "Size in RUS", + "dartzSubmit": "Submit", + "@_SQFLITE": {}, "sqfliteTitleState": "Database state", "sqfliteTitleInsert": "Database insert", diff --git a/example/lib/l10n/app_ru.arb b/example/lib/l10n/app_ru.arb index 5e9a927..b8bd5e4 100644 --- a/example/lib/l10n/app_ru.arb +++ b/example/lib/l10n/app_ru.arb @@ -1,4 +1,37 @@ { + "@_PROVIDER": {}, + "providerTitle": "Provider", + "providerSubtitle": "Простой пример использования пакета provider", + + "@_RXDART": {}, + "rxdartTitle": "Rxdart", + "rxdartSubtitle": "Простой пример использования Rx для Dart", + + "@_TRANSLATOR": {}, + "translatorTitle": "Переводчик", + "translatorSubtitle": "Перевод en -> ru 'Hello!'", + "translatorText": "Hello!", + + "@_EQUATABLE": {}, + "equatableTitleDefault": "Класс по умолчанию, 46 строки", + "equatableTitleFreezed": "Класс c freezed, 26 строк", + "equatableSubtitle": "Методы: toString, operator ==, hashCode.", + + "@_FREEZED": {}, + "freezedTitleDefault": "Класс по умолчанию, 74 строки", + "freezedTitleFreezed": "Класс c freezed, 21 строка", + "freezedSubtitle": "Методы: fromJson, copyWith, toJson, toString, operator ==, hashCode.", + + "@_DARTZ": {}, + "dartzTitle": "Преобразовать размер", + "dartzDesc": "Преобразовать размерную сетку России в размерную сетку Европы.", + "dartzErrorReq": "Обязательное поле", + "dartzErrorInt": "Введите размер RUS (42–62)", + "dartzErrorFound": "Размер не найден (42–62)", + "dartzDefaultValue": "Укажите размер и нажмите 'Отправить'", + "dartzLabel": "Размер в RUS", + "dartzSubmit": "Отправить", + "@_SQFLITE": {}, "sqfliteTitleState": "Состояние базы данных", "sqfliteTitleInsert": "Вставка в базу данных", diff --git a/example/lib/packages/build_runner/package.dart b/example/lib/packages/build_runner/package.dart new file mode 100644 index 0000000..942b083 --- /dev/null +++ b/example/lib/packages/build_runner/package.dart @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_dialog.dart'; + +/// Package values +final packageBuildRunner = PackageDialog( + key: 'build_runner', + descEN: ''' + The build_runner package provides a concrete way of generating files using + Dart code. Files are always generated directly on disk, and rebuilds + are incremental - inspired by tools such as Bazel. + ''', + descRU: ''' + Пакет build_runner предоставляет конкретный способ создания файлов с + использованием кода Dart. Файлы всегда генерируются непосредственно на + диске и перестраиваются являются инкрементными — вдохновлены такими + инструментами, как Bazel. + ''', + messageEN: ''' + This is a platform independent plugin used in this app, should work + for you too. + ''', + messageRU: ''' + Это плагин независимый от платформы, используется в этом приложении, + должен работать и у вас. + ''', + version: '2.3.3', + isPlatformDependent: false, +); diff --git a/example/lib/packages/dartz/model.dart b/example/lib/packages/dartz/model.dart new file mode 100644 index 0000000..0174b47 --- /dev/null +++ b/example/lib/packages/dartz/model.dart @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:dartz/dartz.dart'; +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [DartzPage] +class DartzModel extends Model { + /// Get [ScopedModel] + static DartzModel of(BuildContext context) => + ScopedModel.of(context); + + /// Example using Option from package dartz + Option getEURManSize(int size) { + if (size < 42) return none(); + if (size < 44) return some('XS'); + if (size < 46) return some('S'); + if (size < 48) return some('M'); + if (size < 50) return some('L'); + if (size < 54) return some('XL'); + if (size < 56) return some('XXL'); + if (size < 58) return some('XXXL'); + if (size <= 62) return some('XXXXL'); + return none(); + } +} diff --git a/example/lib/packages/dartz/package.dart b/example/lib/packages/dartz/package.dart new file mode 100644 index 0000000..214a2d9 --- /dev/null +++ b/example/lib/packages/dartz/package.dart @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageDartz = PackagePage( + key: 'dartz', + descEN: ''' + Functional programming in Dart. + ''', + descRU: ''' + Функциональное программирование в Dart. + ''', + version: '0.10.1', + isPlatformDependent: false, + page: () => DartzPage(), + init: () { + GetIt.instance.registerFactory(() => DartzModel()); + }, +); diff --git a/example/lib/packages/dartz/page.dart b/example/lib/packages/dartz/page.dart new file mode 100644 index 0000000..ad74e6a --- /dev/null +++ b/example/lib/packages/dartz/page.dart @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'dart:async'; + +import 'package:flutter/foundation.dart' show kIsAurora; +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_item.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_example_packages/widgets/texts/export.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:flutter_keyboard_visibility_aurora/flutter_keyboard_visibility_aurora.dart'; + +import 'model.dart'; +import 'package.dart'; + +class DartzPage extends AppStatefulWidget { + DartzPage({ + super.key, + }); + + final Package package = packageDartz; + + @override + State createState() => _DartzPageState(); +} + +class _DartzPageState extends AppState { + final TextEditingController _textController = TextEditingController(); + final _formKey = GlobalKey(); + String? _sizeEUR; + bool _isError = false; + + double _keyboardHeight = 0; + StreamSubscription? _streamSub; + final _controllerAurora = FlutterKeyboardVisibilityAurora(); + + @override + void initState() { + super.initState(); + if (kIsAurora) { + _streamSub = _controllerAurora.onChangeHeight.listen((event) { + setState(() { + _keyboardHeight = event; + }); + }); + } + } + + @override + void dispose() { + super.dispose(); + _streamSub?.cancel(); + } + + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + padding: EdgeInsets.only(bottom: _keyboardHeight), + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockItem( + title: l10n.dartzTitle, + desc: l10n.dartzDesc, + value: _sizeEUR ?? l10n.dartzDefaultValue, + ), + TextFormField( + controller: _textController, + keyboardType: TextInputType.number, + decoration: InputDecoration( + labelText: l10n.dartzLabel, + errorText: + _isError ? l10n.dartzErrorFound : null, + ), + validator: (value) { + if (value == null || value.isEmpty) { + return l10n.dartzErrorReq; + } + if (int.tryParse(value) == null) { + return l10n.dartzErrorInt; + } + return null; + }, + ), + const SizedBox(height: 20), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () async { + if (_formKey.currentState?.validate() == true) { + final sizeRU = int.parse(_textController.text); + model + .getEURManSize(sizeRU) + .map( + (classification) => setState(() { + _isError = false; + _sizeEUR = classification; + }), + ) + .getOrElse( + () => setState(() { + _sizeEUR = null; + _isError = true; + }), + ); + } + }, + child: TextBodyLarge( + l10n.dartzSubmit, + color: Colors.white, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/example/lib/packages/equatable/model.dart b/example/lib/packages/equatable/model.dart new file mode 100644 index 0000000..42d7c4b --- /dev/null +++ b/example/lib/packages/equatable/model.dart @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:flutter_example_packages/packages/equatable/user_entity.dart'; +import 'package:flutter_example_packages/packages/equatable/user_entity_equatable.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [EquatablePage] +class EquatableModel extends Model { + /// Get [ScopedModel] + static EquatableModel of(BuildContext context) => + ScopedModel.of(context); + + UserEntity userEntity = const UserEntity( + name: 'Default', + email: 'default@yandex.ru', + age: 12, + ); + + UserEntityEquatable userEntityEquatable= const UserEntityEquatable( + name: 'Equatable', + email: 'default@yandex.ru', + age: 12, + ); +} diff --git a/example/lib/packages/equatable/package.dart b/example/lib/packages/equatable/package.dart new file mode 100644 index 0000000..bb5d85d --- /dev/null +++ b/example/lib/packages/equatable/package.dart @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageEquatable = PackagePage( + key: 'equatable', + descEN: ''' + Being able to compare objects in Dart often involves having to override + the == operator as well as hashCode. + ''', + descRU: ''' + Возможность сравнивать объекты в Dart часто требует переопределения + оператора ==, а также hashCode. + ''', + version: '2.0.5', + isPlatformDependent: false, + page: () => EquatablePage(), + init: () { + GetIt.instance.registerFactory(() => EquatableModel()); + }, +); diff --git a/example/lib/packages/equatable/page.dart b/example/lib/packages/equatable/page.dart new file mode 100644 index 0000000..1df6614 --- /dev/null +++ b/example/lib/packages/equatable/page.dart @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/theme/radius.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_example_packages/widgets/texts/export.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'model.dart'; +import 'package.dart'; + +class EquatablePage extends AppStatefulWidget { + EquatablePage({ + super.key, + }); + + final Package package = packageEquatable; + + @override + State createState() => _EquatablePageState(); +} + +class _EquatablePageState extends AppState { + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + TextTitleLarge(l10n.equatableTitleDefault), + const SizedBox(height: 8), + TextBodyMedium(l10n.equatableSubtitle), + const SizedBox(height: 14), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.blue.shade50, + borderRadius: AppRadius.small, + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: TextBodyMedium(model.userEntity.toString()), + ), + ), + const SizedBox(height: 20), + TextTitleLarge(l10n.equatableTitleFreezed), + const SizedBox(height: 8), + TextBodyMedium(l10n.equatableSubtitle), + const SizedBox(height: 14), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.blue.shade50, + borderRadius: AppRadius.small, + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: TextBodyMedium(model.userEntityEquatable.toString()), + ), + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/example/lib/packages/equatable/user_entity.dart b/example/lib/packages/equatable/user_entity.dart new file mode 100644 index 0000000..28877f3 --- /dev/null +++ b/example/lib/packages/equatable/user_entity.dart @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/foundation.dart'; + +@immutable +class UserEntity { + const UserEntity({ + required this.name, + required this.email, + required this.age, + }); + + final String name; + final String email; + final int age; + + @override + String toString() { + return 'UserEntity(' + '$name,' + '$email,' + '$age' + ')'; + } + + @override + bool operator ==(dynamic other) { + return other is UserEntity && + other.name == name && + other.email == email && + other.age == age; + } + + @override + int get hashCode { + return Object.hash( + runtimeType, + name, + email, + age, + ); + } +} diff --git a/example/lib/packages/equatable/user_entity_equatable.dart b/example/lib/packages/equatable/user_entity_equatable.dart new file mode 100644 index 0000000..950203c --- /dev/null +++ b/example/lib/packages/equatable/user_entity_equatable.dart @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart'; + +@immutable +class UserEntityEquatable extends Equatable { + const UserEntityEquatable({ + required this.name, + required this.email, + required this.age, + }); + + final String name; + final String email; + final int age; + + @override + List get props => [name, email, age]; + + @override + bool get stringify => true; +} diff --git a/example/lib/packages/flutter_markdown/model.dart b/example/lib/packages/flutter_markdown/model.dart new file mode 100644 index 0000000..bd5b831 --- /dev/null +++ b/example/lib/packages/flutter_markdown/model.dart @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [FlutterMarkdownPage] +class FlutterMarkdownModel extends Model { + /// Get [ScopedModel] + static FlutterMarkdownModel of(BuildContext context) => + ScopedModel.of(context); + + final String data = ''' +An h1 header +============ + +Paragraphs are separated by a blank line. + +2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists +look like: + + * this one + * that one + * the other one + +Note that --- not considering the asterisk --- the actual text +content starts at 4-columns in. + +> Block quotes are +> written like so. +> +> They can span multiple paragraphs, +> if you like. + +Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all +in chapters 12--14"). Three dots ... will be converted to an ellipsis. +Unicode is supported. ☺ + +## Image + +![Minion](https://github.com/keygenqt/awesome-aurora/blob/master/docs/assets/images/common/aurora.png?raw=true) + '''; +} diff --git a/example/lib/packages/flutter_markdown/package.dart b/example/lib/packages/flutter_markdown/package.dart new file mode 100644 index 0000000..2caac89 --- /dev/null +++ b/example/lib/packages/flutter_markdown/package.dart @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageFlutterMarkdown = PackagePage( + key: 'flutter_markdown', + descEN: ''' + A markdown renderer for Flutter. It supports the original format, + but no inline HTML. + ''', + descRU: ''' + Рендерер уценки для Flutter. Он поддерживает исходный формат, + но не поддерживает встроенный HTML. + ''', + version: '0.6.15', + isPlatformDependent: false, + page: () => FlutterMarkdownPage(), + init: () { + GetIt.instance + .registerFactory(() => FlutterMarkdownModel()); + }, +); diff --git a/example/lib/packages/flutter_markdown/page.dart b/example/lib/packages/flutter_markdown/page.dart new file mode 100644 index 0000000..3c0ed59 --- /dev/null +++ b/example/lib/packages/flutter_markdown/page.dart @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; + +import 'model.dart'; +import 'package.dart'; + +class FlutterMarkdownPage extends AppStatefulWidget { + FlutterMarkdownPage({ + super.key, + }); + + final Package package = packageFlutterMarkdown; + + @override + State createState() => _FlutterMarkdownPageState(); +} + +class _FlutterMarkdownPageState extends AppState { + final ScrollController _scrollController = ScrollController(); + + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return Column( + children: [ + Flexible( + flex: 0, + child: Padding( + padding: const EdgeInsets.only( + top: 20, + left: 20, + right: 20, + ), + child: BlockInfoPackage(widget.package), + ), + ), + Flexible( + flex: 1, + child: Markdown( + controller: _scrollController, + padding: const EdgeInsets.all(20.0), + data: model.data, + ), + ), + ], + ); + }, + ); + } +} diff --git a/example/lib/packages/freezed/model.dart b/example/lib/packages/freezed/model.dart new file mode 100644 index 0000000..c431b93 --- /dev/null +++ b/example/lib/packages/freezed/model.dart @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:flutter_example_packages/packages/freezed/user_entity.dart'; +import 'package:flutter_example_packages/packages/freezed/user_entity_freezed.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [FreezedPage] +class FreezedModel extends Model { + /// Get [ScopedModel] + static FreezedModel of(BuildContext context) => + ScopedModel.of(context); + + UserEntity userEntity = UserEntity.fromJson(const { + 'name': 'Default', + 'email': 'default@yandex.ru', + 'age': 12, + }); + + UserEntityFreezed userEntityFreezed = UserEntityFreezed.fromJson(const { + 'name': 'Default', + 'email': 'default@yandex.ru', + 'age': 12, + }); +} diff --git a/example/lib/packages/freezed/package.dart b/example/lib/packages/freezed/package.dart new file mode 100644 index 0000000..b94bc2d --- /dev/null +++ b/example/lib/packages/freezed/package.dart @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageFreezed = PackagePage( + key: 'freezed', + descEN: ''' + Code generator for data-classes/unions/pattern-matching/cloning. + ''', + descRU: ''' + Генератор кода для классов данных/объединений/сопоставления + с образцом/клонирования. + ''', + version: '2.3.3', + isPlatformDependent: false, + page: () => FreezedPage(), + init: () { + GetIt.instance.registerFactory(() => FreezedModel()); + }, +); diff --git a/example/lib/packages/freezed/page.dart b/example/lib/packages/freezed/page.dart new file mode 100644 index 0000000..3177f78 --- /dev/null +++ b/example/lib/packages/freezed/page.dart @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/theme/radius.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_example_packages/widgets/texts/export.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'model.dart'; +import 'package.dart'; + +class FreezedPage extends AppStatefulWidget { + FreezedPage({ + super.key, + }); + + final Package package = packageFreezed; + + @override + State createState() => _FreezedPageState(); +} + +class _FreezedPageState extends AppState { + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + TextTitleLarge(l10n.freezedTitleDefault), + const SizedBox(height: 8), + TextBodyMedium(l10n.freezedSubtitle), + const SizedBox(height: 14), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.blue.shade50, + borderRadius: AppRadius.small, + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: TextBodyMedium( + const JsonEncoder.withIndent(' ').convert( + model.userEntity.copyWith(name: 'My name').toJson()), + ), + ), + ), + const SizedBox(height: 20), + TextTitleLarge(l10n.freezedTitleFreezed), + const SizedBox(height: 8), + TextBodyMedium(l10n.freezedSubtitle), + const SizedBox(height: 14), + Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.blue.shade50, + borderRadius: AppRadius.small, + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: TextBodyMedium( + const JsonEncoder.withIndent(' ').convert(model + .userEntityFreezed + .copyWith(name: 'My name') + .toJson()), + ), + ), + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/example/lib/packages/freezed/user_entity.dart b/example/lib/packages/freezed/user_entity.dart new file mode 100644 index 0000000..d852223 --- /dev/null +++ b/example/lib/packages/freezed/user_entity.dart @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/foundation.dart'; + +@immutable +class UserEntity { + const UserEntity({ + required this.name, + required this.email, + required this.age, + }); + + factory UserEntity.fromJson(Map json) { + return UserEntity( + name: json['name'] as String, + email: json['email'] as String, + age: json['age'] as int, + ); + } + + final String name; + final String email; + final int age; + + UserEntity copyWith({ + String? name, + String? email, + int? age, + }) { + return UserEntity( + name: name ?? this.name, + email: email ?? this.email, + age: age ?? this.age, + ); + } + + Map toJson() { + return { + 'name': name, + 'email': email, + 'age': age, + }; + } + + @override + String toString() { + return 'UserEntity(' + 'name: $name' + 'email: $email' + 'age: $age' + ')'; + } + + @override + bool operator ==(dynamic other) { + return other is UserEntity && + other.name == name && + other.email == email && + other.age == age; + } + + @override + int get hashCode { + return Object.hash( + runtimeType, + name, + email, + age, + ); + } +} diff --git a/example/lib/packages/freezed/user_entity_freezed.dart b/example/lib/packages/freezed/user_entity_freezed.dart new file mode 100644 index 0000000..7dd2917 --- /dev/null +++ b/example/lib/packages/freezed/user_entity_freezed.dart @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'user_entity_freezed.freezed.dart'; +part 'user_entity_freezed.g.dart'; + +@freezed +class UserEntityFreezed with _$UserEntityFreezed { + const factory UserEntityFreezed({ + required String name, + required String email, + required int age, + }) = _UserEntityFreezed; + + factory UserEntityFreezed.fromJson(Map json) => + _$UserEntityFreezedFromJson(json); +} diff --git a/example/lib/packages/freezed_annotation/package.dart b/example/lib/packages/freezed_annotation/package.dart new file mode 100644 index 0000000..7fbc8cd --- /dev/null +++ b/example/lib/packages/freezed_annotation/package.dart @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_dialog.dart'; + +/// Package values +final packageFreezedAnnotation = PackageDialog( + key: 'freezed_annotation', + descEN: ''' + Annotations for freezed. This package does nothing without freezed. + ''', + descRU: ''' + Аннотации для freezed. Этот пакет ничего не делает без freezed. + ''', + messageEN: ''' + This is a platform independent plugin used in this application in the demo + of the freezed plugin. + ''', + messageRU: ''' + Это плагин независимый от платформы, используется в этом приложении в + демострации работы плагина freezed. + ''', + version: '2.2.0', + isPlatformDependent: false, +); diff --git a/example/lib/packages/intl/package.dart b/example/lib/packages/intl/package.dart index 6b94749..6080995 100644 --- a/example/lib/packages/intl/package.dart +++ b/example/lib/packages/intl/package.dart @@ -5,22 +5,48 @@ import 'package:flutter_example_packages/base/package/package_dialog.dart'; /// Package values -final packagePath = PackageDialog( - key: 'path', +final packageIntl = PackageDialog( + key: 'intl', descEN: ''' - A comprehensive, cross-platform path manipulation library for Dart. + Provides internationalization and localization facilities, + including message translation, plurals and genders, + date/number formatting and parsing, and bidirectional text. ''', descRU: ''' - Комплексная кроссплатформенная библиотека управления путями для Dart. + Предоставляет средства интернационализации и локализации, + включая перевод сообщений, множественное число и пол, + форматирование и разбор даты/числа, а также двунаправленный текст. ''', messageEN: ''' - This is a platform independent plugin used in this app, should work - for you too. - ''', + This is a platform independent plugin used in this app, should work + for you too. + ''', messageRU: ''' - Это плагин независимый от платформы, используется в этом приложении, - должен работать и у вас. - ''', - version: '1.8.2', + Это плагин независимый от платформы, используется в этом приложении, + должен работать и у вас. + ''', + version: '0.17.0', isPlatformDependent: false, ); + +// @todo +/// Package values +// final packagePath = PackageDialog( +// key: 'path', +// descEN: ''' +// A comprehensive, cross-platform path manipulation library for Dart. +// ''', +// descRU: ''' +// Комплексная кроссплатформенная библиотека управления путями для Dart. +// ''', +// messageEN: ''' +// This is a platform independent plugin used in this app, should work +// for you too. +// ''', +// messageRU: ''' +// Это плагин независимый от платформы, используется в этом приложении, +// должен работать и у вас. +// ''', +// version: '1.8.2', +// isPlatformDependent: false, +// ); diff --git a/example/lib/packages/json_annotation/package.dart b/example/lib/packages/json_annotation/package.dart new file mode 100644 index 0000000..28eeecc --- /dev/null +++ b/example/lib/packages/json_annotation/package.dart @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_dialog.dart'; + +/// Package values +final packageJsonAnnotation = PackageDialog( + key: 'json_annotation', + descEN: ''' + Defines the annotations used by json_serializable to create code for + JSON serialization and deserialization. + ''', + descRU: ''' + Определяет аннотации, используемые json_serializable для создания кода для + JSON Serialization и Deserialization. + ''', + messageEN: ''' + This is a platform independent plugin used in this application in the demo + of the freezed plugin. + ''', + messageRU: ''' + Это плагин независимый от платформы, используется в этом приложении в + демострации работы плагина freezed. + ''', + version: '4.8.0', + isPlatformDependent: false, +); diff --git a/example/lib/packages/json_serializable/package.dart b/example/lib/packages/json_serializable/package.dart new file mode 100644 index 0000000..bbd0ab5 --- /dev/null +++ b/example/lib/packages/json_serializable/package.dart @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_dialog.dart'; + +/// Package values +final packageJsonSerializable = PackageDialog( + key: 'json_serializable', + descEN: ''' + Provides Dart Build System builders for handling JSON. + ''', + descRU: ''' + Предоставляет Dart Build System System для обработки JSON. + ''', + messageEN: ''' + This is a platform independent plugin used in this application in the demo + of the freezed plugin. + ''', + messageRU: ''' + Это плагин независимый от платформы, используется в этом приложении в + демострации работы плагина freezed. + ''', + version: '6.6.1', + isPlatformDependent: false, +); diff --git a/example/lib/packages/packages.dart b/example/lib/packages/packages.dart index 30b9d9f..2fc7228 100644 --- a/example/lib/packages/packages.dart +++ b/example/lib/packages/packages.dart @@ -4,22 +4,34 @@ */ import 'package:flutter_example_packages/base/package/package.dart'; import 'package:flutter_example_packages/packages/battery_plus/package.dart'; +import 'package:flutter_example_packages/packages/build_runner/package.dart'; import 'package:flutter_example_packages/packages/cached_network_image/package.dart'; import 'package:flutter_example_packages/packages/cupertino_icons/package.dart'; +import 'package:flutter_example_packages/packages/dartz/package.dart'; import 'package:flutter_example_packages/packages/device_info_plus/package.dart'; +import 'package:flutter_example_packages/packages/equatable/package.dart'; import 'package:flutter_example_packages/packages/flutter_cache_manager/package.dart'; import 'package:flutter_example_packages/packages/flutter_local_notifications/package.dart'; +import 'package:flutter_example_packages/packages/flutter_markdown/package.dart'; import 'package:flutter_example_packages/packages/flutter_secure_storage/package.dart'; +import 'package:flutter_example_packages/packages/freezed/package.dart'; +import 'package:flutter_example_packages/packages/freezed_annotation/package.dart'; import 'package:flutter_example_packages/packages/get_it/package.dart'; import 'package:flutter_example_packages/packages/google_fonts/package.dart'; import 'package:flutter_example_packages/packages/intl/package.dart'; +import 'package:flutter_example_packages/packages/json_annotation/package.dart'; +import 'package:flutter_example_packages/packages/json_serializable/package.dart'; import 'package:flutter_example_packages/packages/package_info_plus/package.dart'; import 'package:flutter_example_packages/packages/path/package.dart'; import 'package:flutter_example_packages/packages/path_provider/package.dart'; import 'package:flutter_example_packages/packages/photo_view/package.dart'; +import 'package:flutter_example_packages/packages/provider/package.dart'; +import 'package:flutter_example_packages/packages/qr_flutter/package.dart'; +import 'package:flutter_example_packages/packages/rxdart/package.dart'; import 'package:flutter_example_packages/packages/scoped_model/package.dart'; import 'package:flutter_example_packages/packages/shared_preferences/package.dart'; import 'package:flutter_example_packages/packages/sqflite/package.dart'; +import 'package:flutter_example_packages/packages/translator/package.dart'; import 'package:flutter_example_packages/packages/universal_io/package.dart'; import 'package:flutter_example_packages/packages/wakelock/package.dart'; import 'package:flutter_example_packages/packages/xdga_directories/package.dart'; @@ -30,24 +42,36 @@ import 'flutter_keyboard_visibility/package.dart'; /// List app packages final packages = [ packageBatteryPlus, + packageBuildRunner, packageCachedNetworkImage, packageCrypto, packageCupertinoIcons, + packageDartz, packageDeviceInfoPlus, + packageEquatable, packageFlutterCacheManager, packageFlutterKeyboardVisibility, packageFlutterLocalNotifications, + packageFlutterMarkdown, packageFlutterSecureStorage, + packageFreezed, + packageFreezedAnnotation, packageGetIt, packageGoogleFonts, packageIntl, + packageJsonAnnotation, + packageJsonSerializable, packagePackageInfoPlus, packagePath, packagePathProvider, packagePhotoView, + packageProvider, + packageQrFlutter, + packageRxdart, packageScopedModel, packageSharedPreferences, packageSqflite, + packageTranslator, packageUniversalIO, packageWakelock, packageXdgaDirectories, diff --git a/example/lib/packages/provider/model.dart b/example/lib/packages/provider/model.dart new file mode 100644 index 0000000..adbbfe9 --- /dev/null +++ b/example/lib/packages/provider/model.dart @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [ProviderPage] +class ProviderModel extends Model { + /// Get [ScopedModel] + static ProviderModel of(BuildContext context) => + ScopedModel.of(context); +} diff --git a/example/lib/packages/provider/package.dart b/example/lib/packages/provider/package.dart new file mode 100644 index 0000000..845f16e --- /dev/null +++ b/example/lib/packages/provider/package.dart @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageProvider = PackagePage( + key: 'provider', + descEN: ''' + A wrapper around InheritedWidget to make them easier to use and more + reusable. + ''', + descRU: ''' + Оболочка вокруг InheritedWidget, чтобы сделать их более простыми в + использовании и более удобными для повторного использования. + ''', + version: '6.0.5', + isPlatformDependent: false, + page: () => ProviderPage(), + init: () { + GetIt.instance.registerFactory(() => ProviderModel()); + }, +); diff --git a/example/lib/packages/provider/page.dart b/example/lib/packages/provider/page.dart new file mode 100644 index 0000000..ebae7fa --- /dev/null +++ b/example/lib/packages/provider/page.dart @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_item.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; + +import 'model.dart'; +import 'package.dart'; + +class ProviderPage extends AppStatefulWidget { + ProviderPage({ + super.key, + }); + + final Package package = packageProvider; + + @override + State createState() => _ProviderPageState(); +} + +class _ProviderPageState extends AppState { + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return FutureProvider( + initialData: 0, + create: (context) => Future.value(12345), // Set value + child: BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + BlockItem( + title: l10n.providerTitle, + desc: l10n.providerSubtitle, + value: context.watch(), // Get value + ), + ], + ), + ), + ); + }, + ), + ); + } +} diff --git a/example/lib/packages/qr_flutter/model.dart b/example/lib/packages/qr_flutter/model.dart new file mode 100644 index 0000000..7c4b38f --- /dev/null +++ b/example/lib/packages/qr_flutter/model.dart @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [QrFlutterPage] +class QrFlutterModel extends Model { + /// Get [ScopedModel] + static QrFlutterModel of(BuildContext context) => + ScopedModel.of(context); +} diff --git a/example/lib/packages/qr_flutter/package.dart b/example/lib/packages/qr_flutter/package.dart new file mode 100644 index 0000000..59000c0 --- /dev/null +++ b/example/lib/packages/qr_flutter/package.dart @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageQrFlutter = PackagePage( + key: 'qr_flutter', + descEN: ''' + QR.Flutter is a Flutter library for simple and fast QR code rendering + via a Widget or custom painter. + ''', + descRU: ''' + ПQR.Flutter — это библиотека Flutter для простого и быстрого рендеринга + QR-кода с помощью виджета или пользовательского рисовальщика. + ''', + version: '4.0.0', + isPlatformDependent: false, + page: () => QrFlutterPage(), + init: () { + GetIt.instance.registerFactory(() => QrFlutterModel()); + }, +); diff --git a/example/lib/packages/qr_flutter/page.dart b/example/lib/packages/qr_flutter/page.dart new file mode 100644 index 0000000..ee10c68 --- /dev/null +++ b/example/lib/packages/qr_flutter/page.dart @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +import 'model.dart'; +import 'package.dart'; + +class QrFlutterPage extends AppStatefulWidget { + QrFlutterPage({ + super.key, + }); + + final Package package = packageQrFlutter; + + @override + State createState() => _QrFlutterPageState(); +} + +class _QrFlutterPageState extends AppState { + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + Center( + child: QrImage( + data: '1234567890', + version: QrVersions.auto, + size: 200.0, + ), + ) + ], + ), + ), + ); + }, + ); + } +} diff --git a/example/lib/packages/rxdart/model.dart b/example/lib/packages/rxdart/model.dart new file mode 100644 index 0000000..94d01b7 --- /dev/null +++ b/example/lib/packages/rxdart/model.dart @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:rxdart/rxdart.dart'; +import 'package:scoped_model/scoped_model.dart'; + +/// Model for [RxdartPage] +class RxdartModel extends Model { + /// Get [ScopedModel] + static RxdartModel of(BuildContext context) => + ScopedModel.of(context); + + final listObjects = [1, 'First', 2, 'Second', 3, 'Third', null]; + + /// Example of using rxdart + Future> getNumberList() { + return Stream.fromIterable(listObjects) + .doOnEach((notification) { + debugPrint(notification.toString()); + }) + .whereNotNull() + .whereType() + .toList(); + } +} diff --git a/example/lib/packages/rxdart/package.dart b/example/lib/packages/rxdart/package.dart new file mode 100644 index 0000000..861c863 --- /dev/null +++ b/example/lib/packages/rxdart/package.dart @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageRxdart = PackagePage( + key: 'rxdart', + descEN: ''' + RxDart extends the capabilities of Dart Streams and StreamControllers. + ''', + descRU: ''' + RxDart расширяет возможности Dart Streams и StreamControllers. + ''', + version: '0.27.7', + isPlatformDependent: false, + page: () => RxdartPage(), + init: () { + GetIt.instance.registerFactory(() => RxdartModel()); + }, +); diff --git a/example/lib/packages/rxdart/page.dart b/example/lib/packages/rxdart/page.dart new file mode 100644 index 0000000..60eb8c6 --- /dev/null +++ b/example/lib/packages/rxdart/page.dart @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_item.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'model.dart'; +import 'package.dart'; + +class RxdartPage extends AppStatefulWidget { + RxdartPage({ + super.key, + }); + + final Package package = packageRxdart; + + @override + State createState() => _RxdartPageState(); +} + +class _RxdartPageState extends AppState { + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + BlockItem( + title: l10n.rxdartTitle, + desc: l10n.rxdartSubtitle, + future: model.getNumberList(), + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/example/lib/packages/translator/model.dart b/example/lib/packages/translator/model.dart new file mode 100644 index 0000000..a3e2500 --- /dev/null +++ b/example/lib/packages/translator/model.dart @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/widgets.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:translator/translator.dart'; + +/// Model for [TranslatorPage] +class TranslatorModel extends Model { + /// Get [ScopedModel] + static TranslatorModel of(BuildContext context) => + ScopedModel.of(context); + + final translator = GoogleTranslator(); + + Future translate( + String value, + ) async { + return await translator.translate(value, from: 'en', to: 'ru'); + } +} diff --git a/example/lib/packages/translator/package.dart b/example/lib/packages/translator/package.dart new file mode 100644 index 0000000..e60879c --- /dev/null +++ b/example/lib/packages/translator/package.dart @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter_example_packages/base/package/package_page.dart'; +import 'package:get_it/get_it.dart'; + +import 'model.dart'; +import 'page.dart'; + +/// Package values +final packageTranslator = PackagePage( + key: 'translator', + descEN: ''' + Free Google Translate API for Dart. + ''', + descRU: ''' + Бесплатный API Google Translate для Dart. + ''', + version: '0.1.7', + isPlatformDependent: false, + page: () => TranslatorPage(), + init: () { + GetIt.instance.registerFactory(() => TranslatorModel()); + }, +); diff --git a/example/lib/packages/translator/page.dart b/example/lib/packages/translator/page.dart new file mode 100644 index 0000000..dee8e34 --- /dev/null +++ b/example/lib/packages/translator/page.dart @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023. Open Mobile Platform LLC. + * License: Proprietary. + */ +import 'package:flutter/material.dart'; +import 'package:flutter_example_packages/base/di/app_di.dart'; +import 'package:flutter_example_packages/base/package/package.dart'; +import 'package:flutter_example_packages/widgets/base/export.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_info_package.dart'; +import 'package:flutter_example_packages/widgets/blocks/block_item.dart'; +import 'package:flutter_example_packages/widgets/layouts/block_layout.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'model.dart'; +import 'package.dart'; + +class TranslatorPage extends AppStatefulWidget { + TranslatorPage({ + super.key, + }); + + final Package package = packageTranslator; + + @override + State createState() => _TranslatorPageState(); +} + +class _TranslatorPageState extends AppState { + @override + Widget buildWide( + BuildContext context, + MediaQueryData media, + AppLocalizations l10n, + ) { + return BlockLayout( + model: getIt(), + title: widget.package.key, + builder: (context, child, model) { + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + BlockInfoPackage(widget.package), + BlockItem( + title: l10n.translatorTitle, + desc: l10n.translatorSubtitle, + future: model.translate(l10n.translatorText), + builder: (value) => value.text, + ), + ], + ), + ), + ); + }, + ); + } +} diff --git a/example/lib/widgets/blocks/block_item.dart b/example/lib/widgets/blocks/block_item.dart index 0fdc574..09d6b46 100644 --- a/example/lib/widgets/blocks/block_item.dart +++ b/example/lib/widgets/blocks/block_item.dart @@ -11,16 +11,16 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class BlockItem extends AppStatelessWidget { const BlockItem({ super.key, - required this.title, - required this.desc, + this.title, + this.desc, this.value, this.future, this.stream, this.builder, }); - final String title; - final String desc; + final String? title; + final String? desc; final T? value; final Stream? stream; final Future? future; @@ -31,10 +31,24 @@ class BlockItem extends AppStatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - TextTitleLarge(title), - const SizedBox(height: 8), - TextBodyMedium(desc), - const SizedBox(height: 8), + Visibility( + visible: title != null, + child: Column( + children: [ + TextTitleLarge(title ?? ''), + const SizedBox(height: 8), + ], + ), + ), + Visibility( + visible: desc != null, + child: Column( + children: [ + TextBodyMedium(desc ?? ''), + const SizedBox(height: 8), + ], + ), + ), if (snapshot.hasData) TextBodyMedium( builder == null diff --git a/example/pubspec.lock b/example/pubspec.lock index 4f8bcb2..392c8ed 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -206,6 +206,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.2.5" + dartz: + dependency: "direct main" + description: + name: dartz + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.1" dbus: dependency: transitive description: @@ -243,6 +250,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.1" + equatable: + dependency: "direct main" + description: + name: equatable + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -383,6 +397,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.15" flutter_secure_storage: dependency: "direct main" description: @@ -444,6 +465,20 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.3" + freezed_annotation: + dependency: "direct main" + description: + name: freezed_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" frontend_server_client: dependency: transitive description: @@ -522,12 +557,19 @@ packages: source: hosted version: "0.6.4" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation url: "https://pub.dartlang.org" source: hosted version: "4.8.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "6.6.1" lints: dependency: transitive description: @@ -542,6 +584,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + markdown: + dependency: transitive + description: + name: markdown + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.1" matcher: dependency: transitive description: @@ -570,6 +619,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" octo_image: dependency: transitive description: @@ -714,6 +770,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.5" pub_semver: dependency: transitive description: @@ -728,8 +791,22 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.3" - rxdart: + qr: dependency: transitive + description: + name: qr + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + qr_flutter: + dependency: "direct main" + description: + name: qr_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + rxdart: + dependency: "direct main" description: name: rxdart url: "https://pub.dartlang.org" @@ -819,6 +896,20 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" + source_helper: + dependency: transitive + description: + name: source_helper + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.3" source_span: dependency: transitive description: @@ -912,6 +1003,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.1" + translator: + dependency: "direct main" + description: + name: translator + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.7" typed_data: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index b63eab4..5bf727a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -38,6 +38,24 @@ dependencies: photo_view: ^0.14.0 ## https://pub.dev/packages/path path: ^1.8.2 + ## https://pub.dev/packages/dartz + dartz: ^0.10.1 + ## https://pub.dev/packages/provider + provider: ^6.0.5 + ## https://pub.dev/packages/equatable + equatable: ^2.0.5 + ## https://pub.dev/packages/qr_flutter + qr_flutter: ^4.0.0 + ## https://pub.dev/packages/rxdart + rxdart: ^0.27.7 + ## https://pub.dev/packages/translator + translator: ^0.1.7 + ## https://pub.dev/packages/flutter_markdown + flutter_markdown: ^0.6.15 + ## https://pub.dev/packages/freezed_annotation + freezed_annotation: ^2.2.0 + ## https://pub.dev/packages/json_annotation + json_annotation: ^4.8.0 ## https://os-git.omprussia.ru/non-oss/flutter/flutter-plugins/-/tree/master/packages/xdga_directories xdga_directories: @@ -140,8 +158,14 @@ dev_dependencies: flutter_test: sdk: flutter + ## https://pub.dev/packages/flutter_lints @todo flutter_lints: ^2.0.0 + ## https://pub.dev/packages/build_runner build_runner: ^2.3.3 + ## https://pub.dev/packages/freezed + freezed: ^2.3.3 + ## https://pub.dev/packages/json_serializable + json_serializable: ^6.6.1 flutter: generate: true