bs_utils 1.1.0
bs_utils: ^1.1.0 copied to clipboard
Combination of useful utilities used across BS packages.
import 'package:bs_utils/bs_utils.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const BsUtilsExampleApp());
}
class BsUtilsExampleApp extends StatelessWidget {
const BsUtilsExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'bs_utils Showcase',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
useMaterial3: true,
),
home: const ExampleHomePage(),
);
}
}
class ExampleHomePage extends StatefulWidget {
const ExampleHomePage({super.key});
@override
State<ExampleHomePage> createState() => _ExampleHomePageState();
}
class _ExampleHomePageState extends State<ExampleHomePage> {
String _consoleOutput = 'Press the buttons below to see bs_utils in action...\n\n';
void _log(String message) {
setState(() {
_consoleOutput += '$message\n';
});
}
void _demonstrateTimeTracker() {
_log('--- Running TimeTracker Demo ---');
final duration = Tracker.trackSync(() {
// ignore: unused_local_variable
var sum = 0;
for (var i = 0; i < 500000; i++) {
sum += i;
}
});
_log('Loop execution tracked: took ${duration.sMsUsFormatted}\n');
}
void _demonstrateExtensions() {
_log('--- Running Extensions Demo ---');
// 1. Duration & Num extensions
final duration = 90.seconds + 500.milliseconds;
_log('90 seconds + 500 milliseconds = ${duration.dynamicColonSeparated}');
// 2. Iterable extensions
final amounts = [15, 30, 100, 4, 100, 22]; // Included two '100's to show allMaxOf
_log('Max value in list: ${amounts.maxOf((e) => e)}');
_log('All max values (ties): ${amounts.allMaxOf((e) => e)}');
// 3. Platform checking
_log('Is the current platform desktop? ${DevicePlatform.fromIO.isDesktop}\n');
}
Future<void> _demonstrateMethodsUtils() async {
_log('--- Running MethodsUtils Demo ---');
// 1. Safe Execution
_log("1. Trying to parse 'Invalid' safely...");
final result = await MethodsUtils.tryThis(() {
return int.parse('Invalid Number'); // Will safely fail
});
_log('Result: $result (safely returned null)\n');
// 2. Polling / Wait Until
_log('2. Waiting until a condition is met (polling)...');
var counter = 0;
await MethodsUtils.waitUntil(() {
counter++;
return counter == 3;
}, retryEvery: 100.milliseconds);
_log('Done waiting! Counter reached $counter.\n');
// 3. Execution Racing (latestValid)
_log("3. Testing task racing using 'latestValid'...");
var firstRan = false;
var secondRan = false;
// Start overlapping tasks
final first = MethodsUtils.latestValid(() async {
await 500.milliseconds.delay;
}).then((v) => firstRan = v);
final second = MethodsUtils.latestValid(() async {
await 100.milliseconds.delay;
}).then((v) => secondRan = v);
await Future.wait([first, second]);
_log('Overlapping tasks finished.');
_log('First task valid? $firstRan');
_log('Second task valid? $secondRan\n');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('bs_utils Example'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton.icon(
onPressed: _demonstrateExtensions,
icon: const Icon(Icons.extension),
label: const Text('Extensions'),
),
ElevatedButton.icon(
onPressed: _demonstrateTimeTracker,
icon: const Icon(Icons.timer),
label: const Text('TimeTracker'),
),
ElevatedButton.icon(
onPressed: _demonstrateMethodsUtils,
icon: const Icon(Icons.build),
label: const Text('MethodsUtils'),
),
],
),
const SizedBox(height: 20),
Expanded(
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(12),
),
child: SingleChildScrollView(
child: Text(
_consoleOutput,
style: const TextStyle(
color: Colors.greenAccent,
fontFamily: 'monospace',
fontSize: 14,
),
),
),
),
),
],
),
),
);
}
}