18 changed files with 511 additions and 57 deletions
@ -1,3 +1,6 @@ |
|||||||
org.gradle.jvmargs=-Xmx1536M |
org.gradle.jvmargs=-Xmx1536M |
||||||
android.useAndroidX=true |
android.useAndroidX=true |
||||||
android.enableJetifier=true |
android.enableJetifier=true |
||||||
|
flutter.minSdkVersion=19 |
||||||
|
flutter.targetSdkVersion=33 |
||||||
|
flutter.compileSdkVersion=33 |
@ -1,8 +1,66 @@ |
|||||||
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:battery_plus/battery_plus.dart'; |
||||||
|
|
||||||
/// Model for [BatteryPlusPage] |
/// Model for [BatteryPlusPage] |
||||||
class BatteryPlusModel extends Model { |
class BatteryPlusModel extends Model { |
||||||
/// Get [ScopedModel] |
/// Get [ScopedModel] |
||||||
static BatteryPlusModel of(BuildContext context) => ScopedModel.of<BatteryPlusModel>(context); |
static BatteryPlusModel of(BuildContext context) => ScopedModel.of<BatteryPlusModel>(context); |
||||||
|
|
||||||
|
final _battery = Battery(); |
||||||
|
|
||||||
|
/// Error |
||||||
|
String? _error; |
||||||
|
|
||||||
|
/// Public error |
||||||
|
String? get error => _error; |
||||||
|
|
||||||
|
/// Public error |
||||||
|
bool get isError => _error != null; |
||||||
|
|
||||||
|
/// Get battery level in percent 0-100 |
||||||
|
Future<int?> getBatteryLevel() async { |
||||||
|
try { |
||||||
|
return await _battery.batteryLevel; |
||||||
|
} catch (e, s) { |
||||||
|
_error = e.toString(); |
||||||
|
debugPrintStack(stackTrace: s); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/// Get status |
||||||
|
Future<BatteryState?> getBatteryState() async { |
||||||
|
try { |
||||||
|
return await _battery.batteryState; |
||||||
|
} catch (e, s) { |
||||||
|
_error = e.toString(); |
||||||
|
debugPrintStack(stackTrace: s); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/// Check is enable save mode |
||||||
|
Future<bool?> isInBatterySaveMode() async { |
||||||
|
try { |
||||||
|
return await _battery.isInBatterySaveMode; |
||||||
|
} catch (e, s) { |
||||||
|
_error = e.toString(); |
||||||
|
debugPrintStack(stackTrace: s); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/// Stream change state |
||||||
|
Stream<BatteryState> onBatteryStateChanged() async* { |
||||||
|
try { |
||||||
|
yield await _battery.batteryState; |
||||||
|
await for (final state in _battery.onBatteryStateChanged) { |
||||||
|
yield state; |
||||||
|
} |
||||||
|
} catch (e, s) { |
||||||
|
_error = e.toString(); |
||||||
|
debugPrintStack(stackTrace: s); |
||||||
|
} |
||||||
|
} |
||||||
} |
} |
@ -0,0 +1,39 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_example_packages/theme/radius.dart'; |
||||||
|
import 'package:flutter_example_packages/widgets/texts/export.dart'; |
||||||
|
|
||||||
|
/// Alert |
||||||
|
class BlockAlert extends StatelessWidget { |
||||||
|
const BlockAlert( |
||||||
|
this.text, { |
||||||
|
super.key, |
||||||
|
this.color = Colors.redAccent, |
||||||
|
this.padding = const EdgeInsets.only(bottom: 20), |
||||||
|
}); |
||||||
|
|
||||||
|
final EdgeInsets padding; |
||||||
|
final Color color; |
||||||
|
final String? text; |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Visibility( |
||||||
|
visible: text != null, |
||||||
|
child: Padding( |
||||||
|
padding: padding, |
||||||
|
child: Container( |
||||||
|
width: double.infinity, |
||||||
|
padding: const EdgeInsets.all(10), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: color, |
||||||
|
borderRadius: AppRadius.small, |
||||||
|
), |
||||||
|
child: TextBodyMedium( |
||||||
|
'$text', |
||||||
|
color: Colors.white, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
import 'package:flutter/material.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/texts/export.dart'; |
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; |
||||||
|
|
||||||
|
/// Block info package in page |
||||||
|
class BlockInfoPackage extends AppStatelessWidget { |
||||||
|
const BlockInfoPackage( |
||||||
|
this.package, { |
||||||
|
super.key, |
||||||
|
}); |
||||||
|
|
||||||
|
final Package package; |
||||||
|
|
||||||
|
@override |
||||||
|
Widget buildWide( |
||||||
|
BuildContext context, |
||||||
|
MediaQueryData media, |
||||||
|
AppLocalizations l10n, |
||||||
|
) { |
||||||
|
return Container( |
||||||
|
padding: const EdgeInsets.all(12), |
||||||
|
margin: const EdgeInsets.only(bottom: 20), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Colors.grey.shade200, |
||||||
|
borderRadius: AppRadius.small, |
||||||
|
), |
||||||
|
child: Column( |
||||||
|
children: [ |
||||||
|
TextBodyMedium(package.desc), |
||||||
|
const SizedBox(height: 8), |
||||||
|
Divider( |
||||||
|
height: 1, |
||||||
|
color: Colors.grey.shade400, |
||||||
|
), |
||||||
|
const SizedBox(height: 8), |
||||||
|
Row( |
||||||
|
children: [ |
||||||
|
const Icon(Icons.verified, size: 14, color: Colors.green), |
||||||
|
const SizedBox(width: 6), |
||||||
|
TextBodySmall(package.version), |
||||||
|
const SizedBox(width: 10), |
||||||
|
Icon( |
||||||
|
Icons.auto_awesome_motion, |
||||||
|
size: 14, |
||||||
|
color: package.isPlatformDependent |
||||||
|
? Colors.deepOrange |
||||||
|
: Colors.blueAccent, |
||||||
|
), |
||||||
|
const SizedBox(width: 6), |
||||||
|
TextBodySmall( |
||||||
|
package.isPlatformDependent |
||||||
|
? l10n.homeListStateDependent |
||||||
|
: l10n.homeListStateIndependent, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,74 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_example_packages/widgets/base/export.dart'; |
||||||
|
import 'package:flutter_example_packages/widgets/texts/export.dart'; |
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; |
||||||
|
|
||||||
|
/// Block list item |
||||||
|
class BlockItem<T> extends AppStatelessWidget { |
||||||
|
const BlockItem({ |
||||||
|
super.key, |
||||||
|
required this.title, |
||||||
|
required this.desc, |
||||||
|
this.future, |
||||||
|
this.stream, |
||||||
|
this.builder, |
||||||
|
}); |
||||||
|
|
||||||
|
final String title; |
||||||
|
final String desc; |
||||||
|
final Stream<T>? stream; |
||||||
|
final Future<T>? future; |
||||||
|
final Function(T)? builder; |
||||||
|
|
||||||
|
AsyncWidgetBuilder<T> get widgetBuilder => |
||||||
|
(BuildContext context, AsyncSnapshot<T> snapshot) { |
||||||
|
return Column( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
TextTitleSmall(title), |
||||||
|
const SizedBox(height: 8), |
||||||
|
TextBodySmall(desc), |
||||||
|
const SizedBox(height: 8), |
||||||
|
if (snapshot.hasData) |
||||||
|
TextBodyMedium( |
||||||
|
snapshot.data == null |
||||||
|
? '-' |
||||||
|
: (builder == null |
||||||
|
? snapshot.data.toString() |
||||||
|
: builder?.call(snapshot.data as T)), |
||||||
|
), |
||||||
|
if (!snapshot.hasData) |
||||||
|
const SizedBox( |
||||||
|
width: 16, |
||||||
|
height: 16, |
||||||
|
child: CircularProgressIndicator( |
||||||
|
color: Colors.blueAccent, |
||||||
|
strokeWidth: 2, |
||||||
|
), |
||||||
|
), |
||||||
|
const SizedBox(height: 20), |
||||||
|
], |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
@override |
||||||
|
Widget buildWide( |
||||||
|
BuildContext context, |
||||||
|
MediaQueryData media, |
||||||
|
AppLocalizations l10n, |
||||||
|
) { |
||||||
|
if (stream != null) { |
||||||
|
return StreamBuilder( |
||||||
|
stream: stream, |
||||||
|
builder: widgetBuilder, |
||||||
|
); |
||||||
|
} |
||||||
|
if (future != null) { |
||||||
|
return FutureBuilder<T>( |
||||||
|
future: future, |
||||||
|
builder: widgetBuilder, |
||||||
|
); |
||||||
|
} |
||||||
|
throw "Please enter a value stream or future"; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue