18 changed files with 511 additions and 57 deletions
@ -1,3 +1,6 @@
|
||||
org.gradle.jvmargs=-Xmx1536M |
||||
android.useAndroidX=true |
||||
android.enableJetifier=true |
||||
flutter.minSdkVersion=19 |
||||
flutter.targetSdkVersion=33 |
||||
flutter.compileSdkVersion=33 |
@ -1,8 +1,66 @@
|
||||
import 'package:flutter/widgets.dart'; |
||||
import 'package:scoped_model/scoped_model.dart'; |
||||
import 'package:battery_plus/battery_plus.dart'; |
||||
|
||||
/// Model for [BatteryPlusPage] |
||||
class BatteryPlusModel extends Model { |
||||
/// Get [ScopedModel] |
||||
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