Browse Source

[flutter_example_packages] Add xdga_directories, refactoring

merge-requests/21/head
Vitaliy Zarubin 2 years ago
parent
commit
ab699098c0
  1. 20
      example/lib/l10n/app_en.arb
  2. 20
      example/lib/l10n/app_ru.arb
  3. 16
      example/lib/packages/battery_plus/model.dart
  4. 89
      example/lib/packages/battery_plus/page.dart
  5. 101
      example/lib/packages/xdga_directories/model.dart
  6. 66
      example/lib/packages/xdga_directories/page.dart
  7. 208
      example/lib/pages/home/widgets/package_list_item.dart
  8. 2
      example/lib/theme/theme.dart
  9. 24
      example/lib/widgets/blocks/block_item.dart
  10. 58
      example/lib/widgets/layouts/block_layout.dart
  11. 6
      example/lib/widgets/texts/text_base.dart
  12. 1
      example/lib/widgets/texts/text_body_large.dart
  13. 1
      example/lib/widgets/texts/text_body_medium.dart
  14. 1
      example/lib/widgets/texts/text_body_small.dart
  15. 1
      example/lib/widgets/texts/text_headline_large.dart
  16. 1
      example/lib/widgets/texts/text_headline_medium.dart
  17. 1
      example/lib/widgets/texts/text_headline_small.dart
  18. 1
      example/lib/widgets/texts/text_title_large.dart
  19. 1
      example/lib/widgets/texts/text_title_medium.dart
  20. 1
      example/lib/widgets/texts/text_title_small.dart
  21. 7
      example/pubspec.lock
  22. 6
      example/pubspec.yaml

20
example/lib/l10n/app_en.arb

@ -3,12 +3,30 @@
"batteryPlusTitleBatteryLevel": "Battery Level", "batteryPlusTitleBatteryLevel": "Battery Level",
"batteryPlusDescBatteryLevel": "Battery level in percent 0 - 100", "batteryPlusDescBatteryLevel": "Battery level in percent 0 - 100",
"batteryPlusTitleBatteryState": "Battery State", "batteryPlusTitleBatteryState": "Battery State",
"batteryPlusDescBatteryState": "Battery state: full, charging, discharging", "batteryPlusDescBatteryState": "Battery state: full, charging, discharging, unknown",
"batteryPlusTitleBatterySaveMode": "Save Mode", "batteryPlusTitleBatterySaveMode": "Save Mode",
"batteryPlusDescBatterySaveMode": "Check is enable 'Save Mode'", "batteryPlusDescBatterySaveMode": "Check is enable 'Save Mode'",
"batteryPlusTitleBatteryStateLive": "Battery State 'Live'", "batteryPlusTitleBatteryStateLive": "Battery State 'Live'",
"batteryPlusDescBatteryStateLive": "Battery change state stream", "batteryPlusDescBatteryStateLive": "Battery change state stream",
"@_XDGA_DIRECTORIES": {},
"xdgaDirectoriesTitleCacheLocation": "App Data Location",
"xdgaDirectoriesDescCacheLocation": "Directory location where persistent application data can be stored.",
"xdgaDirectoriesTitleAppDataLocation": "Cache Location",
"xdgaDirectoriesDescAppDataLocation": "Directory location where user-specific non-essential (cached) data should be written.",
"xdgaDirectoriesTitleDocumentsLocation": "Documents Location",
"xdgaDirectoriesDescDocumentsLocation": "Directory containing user document files.",
"xdgaDirectoriesTitleDownloadLocation": "Download Location",
"xdgaDirectoriesDescDownloadLocation": "Directory for user's downloaded files.",
"xdgaDirectoriesTitleMusicLocation": "Music Location",
"xdgaDirectoriesDescMusicLocation": "Directory containing the user's music or other audio files.",
"xdgaDirectoriesTitlePicturesLocation": "Pictures Location",
"xdgaDirectoriesDescPicturesLocation": "Directory containing the user's pictures or photos.",
"xdgaDirectoriesTitleGenericDataLocation": "Generic Data Location",
"xdgaDirectoriesDescGenericDataLocation": "Directory location where persistent data shared across applications can be stored.",
"xdgaDirectoriesTitleMoviesLocation": "Movies Location",
"xdgaDirectoriesDescMoviesLocation": "Directory containing the user's movies and videos.",
"@_COMMON": {}, "@_COMMON": {},
"commonClose": "Close", "commonClose": "Close",
"commonEmptyValue": "Empty", "commonEmptyValue": "Empty",

20
example/lib/l10n/app_ru.arb

@ -3,12 +3,30 @@
"batteryPlusTitleBatteryLevel": "Уровень заряда батареи", "batteryPlusTitleBatteryLevel": "Уровень заряда батареи",
"batteryPlusDescBatteryLevel": "Уровень заряда батареи в процентах от 0 до 100", "batteryPlusDescBatteryLevel": "Уровень заряда батареи в процентах от 0 до 100",
"batteryPlusTitleBatteryState": "Состояние батареи", "batteryPlusTitleBatteryState": "Состояние батареи",
"batteryPlusDescBatteryState": "Состояния: full, charging, discharging", "batteryPlusDescBatteryState": "Состояния: full, charging, discharging, unknown",
"batteryPlusTitleBatterySaveMode": "Save Mode", "batteryPlusTitleBatterySaveMode": "Save Mode",
"batteryPlusDescBatterySaveMode": "Проверка включен ли режим 'Save Mode'", "batteryPlusDescBatterySaveMode": "Проверка включен ли режим 'Save Mode'",
"batteryPlusTitleBatteryStateLive": "Состояние батареи 'Live'", "batteryPlusTitleBatteryStateLive": "Состояние батареи 'Live'",
"batteryPlusDescBatteryStateLive": "Изменение состояния батареи", "batteryPlusDescBatteryStateLive": "Изменение состояния батареи",
"@_XDGA_DIRECTORIES": {},
"xdgaDirectoriesTitleCacheLocation": "App Data Location",
"xdgaDirectoriesDescCacheLocation": "Расположение каталога, в котором могут храниться постоянные данные приложения.",
"xdgaDirectoriesTitleAppDataLocation": "Cache Location",
"xdgaDirectoriesDescAppDataLocation": "Расположение каталога, в котором должны быть записаны второстепенные (кэшированные) данные пользователя.",
"xdgaDirectoriesTitleDocumentsLocation": "Documents Location",
"xdgaDirectoriesDescDocumentsLocation": "Каталог, содержащий файлы документов пользователя.",
"xdgaDirectoriesTitleDownloadLocation": "Download Location",
"xdgaDirectoriesDescDownloadLocation": "Каталог для загруженных пользователем файлов.",
"xdgaDirectoriesTitleMusicLocation": "Music Location",
"xdgaDirectoriesDescMusicLocation": "Каталог, содержащий музыку пользователя или другие аудиофайлы.",
"xdgaDirectoriesTitlePicturesLocation": "Pictures Location",
"xdgaDirectoriesDescPicturesLocation": "Каталог, содержащий изображения или фотографии пользователя.",
"xdgaDirectoriesTitleGenericDataLocation": "Generic Data Location",
"xdgaDirectoriesDescGenericDataLocation": "Расположение каталога, в котором могут храниться постоянные данные, совместно используемые приложениями.",
"xdgaDirectoriesTitleMoviesLocation": "Movies Location",
"xdgaDirectoriesDescMoviesLocation": "Каталог, содержащий фильмы и видео пользователя.",
"@_COMMON": {}, "@_COMMON": {},
"commonClose": "Закрыть", "commonClose": "Закрыть",
"commonEmptyValue": "Пусто", "commonEmptyValue": "Пусто",

16
example/lib/packages/battery_plus/model.dart

@ -22,10 +22,10 @@ class BatteryPlusModel extends Model {
Future<int?> getBatteryLevel() async { Future<int?> getBatteryLevel() async {
try { try {
return await _battery.batteryLevel; return await _battery.batteryLevel;
} catch (e, s) { } catch (e) {
_error = e.toString(); _error = e.toString();
debugPrintStack(stackTrace: s);
} }
notifyListeners();
return null; return null;
} }
@ -33,10 +33,10 @@ class BatteryPlusModel extends Model {
Future<BatteryState?> getBatteryState() async { Future<BatteryState?> getBatteryState() async {
try { try {
return await _battery.batteryState; return await _battery.batteryState;
} catch (e, s) { } catch (e) {
_error = e.toString(); _error = e.toString();
debugPrintStack(stackTrace: s);
} }
notifyListeners();
return null; return null;
} }
@ -44,10 +44,10 @@ class BatteryPlusModel extends Model {
Future<bool?> isInBatterySaveMode() async { Future<bool?> isInBatterySaveMode() async {
try { try {
return await _battery.isInBatterySaveMode; return await _battery.isInBatterySaveMode;
} catch (e, s) { } catch (e) {
_error = e.toString(); _error = e.toString();
debugPrintStack(stackTrace: s);
} }
notifyListeners();
return null; return null;
} }
@ -58,9 +58,9 @@ class BatteryPlusModel extends Model {
await for (final state in _battery.onBatteryStateChanged) { await for (final state in _battery.onBatteryStateChanged) {
yield state; yield state;
} }
} catch (e, s) { } catch (e) {
_error = e.toString(); _error = e.toString();
debugPrintStack(stackTrace: s); notifyListeners();
} }
} }
} }

89
example/lib/packages/battery_plus/page.dart

@ -28,50 +28,49 @@ class _BatteryPlusPageState extends AppState<BatteryPlusPage> {
AppLocalizations l10n, AppLocalizations l10n,
) { ) {
return BlockLayout<BatteryPlusModel>( return BlockLayout<BatteryPlusModel>(
title: widget.package.key, title: widget.package.key,
builder: (context, child, model) { builder: (context, child, model) {
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
BlockInfoPackage(widget.package), BlockInfoPackage(widget.package),
BlockAlert(model.error), BlockAlert(model.error),
Visibility( if (!model.isError)
visible: model.error == null, Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ BlockItem(
BlockItem( title: l10n.batteryPlusTitleBatteryLevel,
title: l10n.batteryPlusTitleBatteryLevel, desc: l10n.batteryPlusDescBatteryLevel,
desc: l10n.batteryPlusDescBatteryLevel, future: model.getBatteryLevel(),
future: model.getBatteryLevel(), builder: (value) => '$value%',
builder: (value) => '$value%', ),
), BlockItem(
BlockItem( title: l10n.batteryPlusTitleBatteryState,
title: l10n.batteryPlusTitleBatteryState, desc: l10n.batteryPlusDescBatteryState,
desc: l10n.batteryPlusDescBatteryState, future: model.getBatteryState(),
future: model.getBatteryState(), builder: (value) =>
builder: (value) => value.toString().split('.').last.toUpperCase(),
value.toString().split('.').last.toUpperCase(), ),
), BlockItem(
BlockItem( title: l10n.batteryPlusTitleBatterySaveMode,
title: l10n.batteryPlusTitleBatterySaveMode, desc: l10n.batteryPlusDescBatterySaveMode,
desc: l10n.batteryPlusDescBatterySaveMode, future: model.isInBatterySaveMode(),
future: model.isInBatterySaveMode(), ),
), BlockItem(
BlockItem( title: l10n.batteryPlusTitleBatteryStateLive,
title: l10n.batteryPlusTitleBatteryStateLive, desc: l10n.batteryPlusDescBatteryStateLive,
desc: l10n.batteryPlusDescBatteryStateLive, stream: model.onBatteryStateChanged(),
stream: model.onBatteryStateChanged(), builder: (value) =>
builder: (value) => value.toString().split('.').last.toUpperCase(),
value.toString().split('.').last.toUpperCase(), ),
), ],
], ),
), ],
) ),
], );
), },
); );
});
} }
} }

101
example/lib/packages/xdga_directories/model.dart

@ -1,8 +1,107 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:scoped_model/scoped_model.dart'; import 'package:scoped_model/scoped_model.dart';
import 'package:xdga_directories/xdga_directories.dart' as xdga;
/// Model for [XdgaDirectoriesPage] /// Model for [XdgaDirectoriesPage]
class XdgaDirectoriesModel extends Model { class XdgaDirectoriesModel extends Model {
/// Get [ScopedModel] /// Get [ScopedModel]
static XdgaDirectoriesModel of(BuildContext context) => ScopedModel.of<XdgaDirectoriesModel>(context); static XdgaDirectoriesModel of(BuildContext context) =>
ScopedModel.of<XdgaDirectoriesModel>(context);
/// Error
String? _error;
/// Public error
String? get error => _error;
/// Public error
bool get isError => _error != null;
/// QStandardPaths::CacheLocation
String? getCacheLocation() {
try {
return xdga.getCacheLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::AppDataLocation
String? getAppDataLocation() {
try {
return xdga.getAppDataLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::DocumentsLocation
String? getDocumentsLocation() {
try {
return xdga.getDocumentsLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::DownloadLocation
String? getDownloadLocation() {
try {
return xdga.getDownloadLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::MusicLocation
String? getMusicLocation() {
try {
return xdga.getMusicLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::PicturesLocation
String? getPicturesLocation() {
try {
return xdga.getPicturesLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::GenericDataLocation
String? getGenericDataLocation() {
try {
return xdga.getGenericDataLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
/// QStandardPaths::MoviesLocation
String? getMoviesLocation() {
try {
return xdga.getMoviesLocation();
} catch (e) {
_error = e.toString();
}
notifyListeners();
return null;
}
} }

66
example/lib/packages/xdga_directories/page.dart

@ -3,6 +3,9 @@ import 'package:flutter_example_packages/base/package/package.dart';
import 'package:flutter_example_packages/packages/xdga_directories/model.dart'; import 'package:flutter_example_packages/packages/xdga_directories/model.dart';
import 'package:flutter_example_packages/packages/xdga_directories/package.dart'; import 'package:flutter_example_packages/packages/xdga_directories/package.dart';
import 'package:flutter_example_packages/widgets/base/export.dart'; import 'package:flutter_example_packages/widgets/base/export.dart';
import 'package:flutter_example_packages/widgets/blocks/block_alert.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/layouts/block_layout.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -25,9 +28,64 @@ class _XdgaDirectoriesPageState extends AppState<XdgaDirectoriesPage> {
AppLocalizations l10n, AppLocalizations l10n,
) { ) {
return BlockLayout<XdgaDirectoriesModel>( return BlockLayout<XdgaDirectoriesModel>(
title: widget.package.key, title: widget.package.key,
builder: (context, child, model) { builder: (context, child, model) {
return Text(widget.package.desc); return SingleChildScrollView(
}); child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BlockInfoPackage(widget.package),
BlockAlert(model.error),
if (!model.isError)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
BlockItem(
title: l10n.xdgaDirectoriesTitleCacheLocation,
desc: l10n.xdgaDirectoriesDescCacheLocation,
value: model.getCacheLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitleAppDataLocation,
desc: l10n.xdgaDirectoriesDescAppDataLocation,
value: model.getAppDataLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitleDocumentsLocation,
desc: l10n.xdgaDirectoriesDescDocumentsLocation,
value: model.getDocumentsLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitleDownloadLocation,
desc: l10n.xdgaDirectoriesDescDownloadLocation,
value: model.getDownloadLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitleMusicLocation,
desc: l10n.xdgaDirectoriesDescMusicLocation,
value: model.getMusicLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitlePicturesLocation,
desc: l10n.xdgaDirectoriesDescPicturesLocation,
value: model.getPicturesLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitleGenericDataLocation,
desc: l10n.xdgaDirectoriesDescGenericDataLocation,
value: model.getGenericDataLocation(),
),
BlockItem(
title: l10n.xdgaDirectoriesTitleMoviesLocation,
desc: l10n.xdgaDirectoriesDescMoviesLocation,
value: model.getMoviesLocation(),
),
],
),
],
),
);
},
);
} }
} }

208
example/lib/pages/home/widgets/package_list_item.dart

@ -25,117 +25,131 @@ class PackageListItemWidget extends AppStatelessWidget {
MediaQueryData media, MediaQueryData media,
AppLocalizations l10n, AppLocalizations l10n,
) { ) {
return Container( return Stack(
decoration: BoxDecoration( children: [
color: Colors.blueGrey, Visibility(
borderRadius: index == 0 visible: index != 0,
? const BorderRadius.only( child: Container(
topLeft: Radius.circular(20), height: 10,
topRight: Radius.circular(20), width: double.infinity,
) transform: Matrix4.translationValues(0.0, -10, 0.0),
: null, color: Colors.blueGrey,
), ),
child: Padding( ),
padding: index == 0 Container(
? const EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 0) decoration: BoxDecoration(
: const EdgeInsets.symmetric(horizontal: 20), color: Colors.blueGrey,
child: Column( borderRadius: index == 0
children: [ ? const BorderRadius.only(
Stack( topLeft: Radius.circular(20),
topRight: Radius.circular(20),
)
: null,
),
child: Padding(
padding: index == 0
? const EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 0)
: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [ children: [
Padding( Stack(
padding: const EdgeInsets.only(top: 10), children: [
child: Stack( Padding(
children: [ padding: const EdgeInsets.only(top: 10),
SizedBox( child: Stack(
width: double.infinity, children: [
child: Card( SizedBox(
color: Colors.white, width: double.infinity,
child: Padding( child: Card(
padding: const EdgeInsets.all(20), color: Colors.white,
child: Column( child: Padding(
crossAxisAlignment: CrossAxisAlignment.start, padding: const EdgeInsets.all(20),
children: [ child: Column(
TextTitleSmall(item.key), crossAxisAlignment: CrossAxisAlignment.start,
const SizedBox(height: 10), children: [
TextBodyMedium( TextTitleSmall(item.key),
item.desc, const SizedBox(height: 10),
color: Colors.black.withOpacity(0.6), TextBodyMedium(
), item.desc,
const SizedBox(height: 12), color: Colors.black.withOpacity(0.6),
Divider( ),
height: 1, const SizedBox(height: 12),
color: AppColors.primary.withOpacity(0.2), Divider(
height: 1,
color: AppColors.primary.withOpacity(0.2),
),
const SizedBox(height: 12),
TextBodySmall(
l10n.homeListVersion(item.version),
color: AppColors.primary.withOpacity(0.7),
),
],
), ),
const SizedBox(height: 12), ),
TextBodySmall(
l10n.homeListVersion(item.version),
color: AppColors.primary.withOpacity(0.7),
),
],
), ),
), ),
), Positioned.fill(
), child: Material(
Positioned.fill( color: Colors.transparent,
child: Material( child: InkWell(
color: Colors.transparent, customBorder: RoundedRectangleBorder(
child: InkWell( borderRadius: AppRadius.small,
customBorder: RoundedRectangleBorder( ),
borderRadius: AppRadius.small, hoverColor: Colors.transparent,
onTap: () {
if (item is PackagePage) {
Navigator.pushNamed(
context, '/${item.key}');
} else if (item is PackageDialog) {
showDialog(
context: context,
builder: (BuildContext context) {
return PackageInfoDialog(
package: item as PackageDialog,
);
});
}
},
),
), ),
hoverColor: Colors.transparent,
onTap: () {
if (item is PackagePage) {
Navigator.pushNamed(context, '/${item.key}');
} else if (item is PackageDialog) {
showDialog(
context: context,
builder: (BuildContext context) {
return PackageInfoDialog(
package: item as PackageDialog,
);
});
}
},
), ),
), ],
), ),
],
),
),
Align(
alignment: FractionalOffset.topRight,
child: Container(
margin: const EdgeInsets.only(right: 16),
decoration: BoxDecoration(
color: item.isPlatformDependent
? Colors.deepOrangeAccent
: Colors.blueAccent,
borderRadius: AppRadius.small,
), ),
child: Padding( Align(
padding: const EdgeInsets.only( alignment: FractionalOffset.topRight,
left: 6, child: Container(
top: 3, margin: const EdgeInsets.only(right: 16),
right: 6, decoration: BoxDecoration(
bottom: 6, color: item.isPlatformDependent
), ? Colors.deepOrangeAccent
child: TextBodySmall( : Colors.blueAccent,
item.isPlatformDependent borderRadius: AppRadius.small,
? l10n.homeListStateDependent ),
: l10n.homeListStateIndependent, child: Padding(
color: Colors.white, padding: const EdgeInsets.only(
left: 6,
top: 3,
right: 6,
bottom: 6,
),
child: TextBodySmall(
item.isPlatformDependent
? l10n.homeListStateDependent
: l10n.homeListStateIndependent,
color: Colors.white,
),
),
), ),
), ),
), ],
), ),
const SizedBox(height: 20),
], ],
), ),
const SizedBox(height: 20), ),
],
), ),
), ],
); );
} }
} }

2
example/lib/theme/theme.dart

@ -70,7 +70,7 @@ final appTheme = ThemeData(
height: 1.3, height: 1.3,
), ),
bodyMedium: GoogleFonts.openSans( bodyMedium: GoogleFonts.openSans(
fontSize: 14, fontSize: 16,
height: 1.3, height: 1.3,
), ),
bodySmall: GoogleFonts.openSans( bodySmall: GoogleFonts.openSans(

24
example/lib/widgets/blocks/block_item.dart

@ -9,6 +9,7 @@ class BlockItem<T> extends AppStatelessWidget {
super.key, super.key,
required this.title, required this.title,
required this.desc, required this.desc,
this.value,
this.future, this.future,
this.stream, this.stream,
this.builder, this.builder,
@ -16,26 +17,26 @@ class BlockItem<T> extends AppStatelessWidget {
final String title; final String title;
final String desc; final String desc;
final T? value;
final Stream<T>? stream; final Stream<T>? stream;
final Future<T>? future; final Future<T>? future;
final Function(T)? builder; final Function(T)? builder;
AsyncWidgetBuilder<T> get widgetBuilder => AsyncWidgetBuilder<T?> get widgetBuilder =>
(BuildContext context, AsyncSnapshot<T> snapshot) { (BuildContext context, AsyncSnapshot<T?> snapshot) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
TextTitleSmall(title), TextTitleSmall(title),
const SizedBox(height: 8), const SizedBox(height: 8),
TextBodySmall(desc), TextBodyMedium(desc),
const SizedBox(height: 8), const SizedBox(height: 8),
if (snapshot.hasData) if (snapshot.hasData)
TextBodyMedium( TextBodyMedium(
snapshot.data == null builder == null
? '-' ? snapshot.data.toString()
: (builder == null : builder?.call(snapshot.data as T),
? snapshot.data.toString() fontWeight: FontWeight.bold,
: builder?.call(snapshot.data as T)),
), ),
if (!snapshot.hasData) if (!snapshot.hasData)
const SizedBox( const SizedBox(
@ -64,11 +65,14 @@ class BlockItem<T> extends AppStatelessWidget {
); );
} }
if (future != null) { if (future != null) {
return FutureBuilder<T>( return FutureBuilder(
future: future, future: future,
builder: widgetBuilder, builder: widgetBuilder,
); );
} }
throw "Please enter a value stream or future"; return FutureBuilder(
future: Future.value(value),
builder: widgetBuilder,
);
} }
} }

58
example/lib/widgets/layouts/block_layout.dart

@ -24,38 +24,40 @@ class BlockLayout<T extends Model> extends AppStatelessWidget {
) { ) {
return ScopedModel<T>( return ScopedModel<T>(
model: getIt<T>(), model: getIt<T>(),
child: ScopedModelDescendant<T>(builder: (context, child, model) { child: ScopedModelDescendant<T>(
return Scaffold( builder: (context, child, model) {
appBar: title == null return Scaffold(
? null appBar: title == null
: AppBar( ? null
leading: Padding( : AppBar(
padding: const EdgeInsets.all(8.0), leading: Padding(
child: ClipOval( padding: const EdgeInsets.all(8.0),
child: Material( child: ClipOval(
color: Colors.blueGrey, child: Material(
child: IconButton( color: Colors.blueGrey,
icon: const Icon(Icons.arrow_back), child: IconButton(
tooltip: 'Back', icon: const Icon(Icons.arrow_back),
onPressed: () { tooltip: 'Back',
Navigator.of(context).pop(); onPressed: () {
}, Navigator.of(context).pop();
},
),
), ),
), ),
), ),
backgroundColor: AppColors.primary,
title: TextTitleSmall(
title!,
color: Colors.white,
),
), ),
backgroundColor: AppColors.primary, body: Padding(
title: TextTitleSmall( padding: EdgeInsets.all(title == null ? 0 : 20),
title!, child: builder.call(context, child, model),
color: Colors.white, ),
), );
), },
body: Padding( ),
padding: EdgeInsets.all(title == null ? 0 : 20),
child: builder.call(context, child, model),
),
);
}),
); );
} }
} }

6
example/lib/widgets/texts/text_base.dart

@ -6,11 +6,13 @@ class TextBase extends StatelessWidget {
super.key, super.key,
this.color, this.color,
this.textAlign, this.textAlign,
this.fontWeight,
}); });
final String data; final String data;
final Color? color; final Color? color;
final TextAlign? textAlign; final TextAlign? textAlign;
final FontWeight? fontWeight;
TextStyle? getStyle(BuildContext context) { TextStyle? getStyle(BuildContext context) {
return Theme.of(context).textTheme.bodyMedium; return Theme.of(context).textTheme.bodyMedium;
@ -20,7 +22,9 @@ class TextBase extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Text( return Text(
data, data,
style: getStyle(context)?.copyWith(color: color ?? Colors.black), style: getStyle(context)?.copyWith(color: color ?? Colors.black).copyWith(
fontWeight: fontWeight,
),
textAlign: textAlign, textAlign: textAlign,
); );
} }

1
example/lib/widgets/texts/text_body_large.dart

@ -6,6 +6,7 @@ class TextBodyLarge extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_body_medium.dart

@ -6,6 +6,7 @@ class TextBodyMedium extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_body_small.dart

@ -6,6 +6,7 @@ class TextBodySmall extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_headline_large.dart

@ -6,6 +6,7 @@ class TextHeadlineLarge extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_headline_medium.dart

@ -6,6 +6,7 @@ class TextHeadlineMedium extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_headline_small.dart

@ -6,6 +6,7 @@ class TextHeadlineSmall extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_title_large.dart

@ -6,6 +6,7 @@ class TextTitleLarge extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_title_medium.dart

@ -6,6 +6,7 @@ class TextTitleMedium extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

1
example/lib/widgets/texts/text_title_small.dart

@ -6,6 +6,7 @@ class TextTitleSmall extends TextBase {
super.key, super.key,
super.color, super.color,
super.textAlign, super.textAlign,
super.fontWeight,
}); });
@override @override

7
example/pubspec.lock

@ -607,6 +607,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
xdga_directories:
dependency: "direct main"
description:
path: "../packages/xdga_directories"
relative: true
source: path
version: "0.0.1"
xml: xml:
dependency: transitive dependency: transitive
description: description:

6
example/pubspec.yaml

@ -26,9 +26,9 @@ dependencies:
## https://pub.dev/packages/universal_io ## https://pub.dev/packages/universal_io
universal_io: ^2.2.0 universal_io: ^2.2.0
# ## https://os-git.omprussia.ru/non-oss/flutter/flutter-plugins/-/tree/master/packages/xdga_directories ## https://os-git.omprussia.ru/non-oss/flutter/flutter-plugins/-/tree/master/packages/xdga_directories
# xdga_directories: xdga_directories:
# path: ../packages/xdga_directories path: ../packages/xdga_directories
## https://pub.dev/packages/battery_plus ## https://pub.dev/packages/battery_plus
battery_plus: ^4.0.1 battery_plus: ^4.0.1

Loading…
Cancel
Save