okane/lib/ui/utils.dart

145 lines
4.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:okane/database/collections/template.dart';
import 'package:okane/screen.dart';
import 'package:okane/ui/state/core.dart';
Future<T?> showDialogOrModal<T>({
required BuildContext context,
required WidgetBuilder builder,
bool showDragHandle = true,
bool horizontalPaddingOnMobile = true,
}) {
final screenSize = getScreenSize(context);
final width = MediaQuery.sizeOf(context).shortestSide;
return switch (screenSize) {
ScreenSize.small => showModalBottomSheet<T>(
context: context,
showDragHandle: showDragHandle,
isScrollControlled: true,
builder:
(context) => Padding(
padding: EdgeInsets.only(
bottom: 32 + MediaQuery.of(context).viewInsets.bottom,
left: horizontalPaddingOnMobile ? 16 : 0,
right: horizontalPaddingOnMobile ? 16 : 0,
),
child: builder(context),
),
),
ScreenSize.normal => showDialog<T>(
context: context,
builder:
(context) => Dialog(
child: Padding(
padding: EdgeInsets.only(top: 16),
child: Container(
constraints: BoxConstraints(maxWidth: width * 0.7),
child: Padding(
padding: EdgeInsets.only(bottom: 32),
child: builder(context),
),
),
),
),
),
};
}
Future<TransactionTemplate?> selectTransactionTemplate(BuildContext context) {
return showDialogOrModal<TransactionTemplate>(
context: context,
builder: (context) {
return BlocBuilder<CoreCubit, CoreState>(
builder: (context, state) {
if (state.transactionTemplates.isEmpty) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text("No templates defined"),
);
}
return ListView.builder(
itemCount: state.transactionTemplates.length,
itemBuilder:
(context, index) => ListTile(
title: Text(state.transactionTemplates[index].name),
onTap: () {
Navigator.of(
context,
).pop(state.transactionTemplates[index]);
},
),
);
},
);
},
);
}
DateTime toMidnight(DateTime t) {
return DateTime(t.year, t.month, t.day);
}
String zeroPad(int i) {
if (i <= 9) {
return "0$i";
}
return i.toString();
}
String formatDateTime(DateTime dt, {bool formatYear = true}) {
if (!formatYear) {
return "${zeroPad(dt.day)}.${zeroPad(dt.month)}";
}
return "${zeroPad(dt.day)}.${zeroPad(dt.month)}.${zeroPad(dt.year)}";
}
Color colorHash(String text) {
final hue =
text.characters
.map((c) => c.codeUnitAt(0).toDouble())
.reduce((acc, c) => c + ((acc.toInt() << 5) - acc)) %
360;
return HSVColor.fromAHSV(1, hue, 0.5, 0.5).toColor();
}
String formatCurrency(double amount, {bool precise = true}) {
if (!precise) {
return "${amount.toInt()}";
}
return "${amount.toStringAsFixed(2)}";
}
DateTime monthEnding(DateTime now) {
return DateTime(now.year, now.month, 32, 23, 59, 59);
}
Future<bool> confirm(BuildContext context, String title, String body) async {
final result = await showDialog<bool>(
context: context,
builder:
(context) => AlertDialog(
title: Text(title),
content: Text(body),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: Text("Delete", style: TextStyle(color: Colors.red)),
),
TextButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text("Cancel"),
),
],
),
);
return result ?? false;
}