Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

use fractions FontFeature #43

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 2 additions & 24 deletions lib/components/widgets/recipe_detail_tabbar_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:untare/cubits/settings_cubit.dart';
import 'package:untare/models/ingredient.dart';
import 'package:untare/models/recipe.dart';
import 'package:untare/extensions/double_extension.dart';
import 'package:flutter_gen/gen_l10n/app_locales.dart';
import 'package:collapsible/collapsible.dart';
import 'package:fraction/fraction.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:untare/utils.dart';

class RecipeDetailTabBarWidget extends StatefulWidget {
final Recipe recipe;
Expand Down Expand Up @@ -274,27 +273,6 @@ class RecipeDetailTabBarWidgetState extends State<RecipeDetailTabBarWidget> {
bool? useFractions = (settingsCubit.state.userServerSetting!.useFractions == true);

double rawAmount = ingredient.amount * newServing / initServing;
String amount = (ingredient.amount > 0) ? ('${rawAmount.toFormattedString()} ') : '';
if (amount != '' && useFractions == true && (rawAmount % 1) != 0) {
// If we have a complex decimal we build a "simple" fraction. Otherwise we do the normal one
if ((((rawAmount - rawAmount.toInt()) * 100) % 5) != 0) {
// Use this crap because we can't change precision programmatically
if (rawAmount.toInt() < 1) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-1).reduce()} ';
} else if (rawAmount.toInt() < 10) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-2).reduce()} ';
} else if (rawAmount.toInt() < 100) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-3).reduce()} ';
} else if(rawAmount.toInt() < 1000) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-4).reduce()} ';
} else {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-5).reduce()} ';
}
} else {
amount = '${MixedFraction.fromDouble(rawAmount)} ';
}
}

String unit = (ingredient.amount > 0 && ingredient.unit != null) ? ('${ingredient.unit!.getUnitName(rawAmount)} ') : '';
String food = (ingredient.food != null) ? ('${ingredient.food!.getFoodName(rawAmount)} ') : '';
String note = (ingredient.note != null && ingredient.note != '') ? ('(${ingredient.note!})') : '';
Expand All @@ -315,7 +293,7 @@ class RecipeDetailTabBarWidgetState extends State<RecipeDetailTabBarWidget> {
contentPadding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
title: Wrap(
children: [
Text(amount, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
amountWrap(rawAmount, useFractions),
Text(unit, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
Text(food, style: const TextStyle(fontSize: 15)),
Text(
Expand Down
27 changes: 3 additions & 24 deletions lib/components/widgets/recipe_shopping_list_stateful_widget.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_locales.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fraction/fraction.dart';
import 'package:untare/blocs/recipe/recipe_bloc.dart';
import 'package:untare/blocs/recipe/recipe_event.dart';
import 'package:untare/blocs/recipe/recipe_state.dart';
import 'package:untare/blocs/shopping_list/shopping_list_bloc.dart';
import 'package:untare/components/loading_component.dart';
import 'package:untare/cubits/settings_cubit.dart';
import 'package:untare/extensions/double_extension.dart';
import 'package:untare/models/food.dart';
import 'package:untare/models/ingredient.dart';
import 'package:untare/models/recipe.dart';
Expand All @@ -17,6 +15,8 @@ import 'package:untare/models/step.dart';
import 'package:untare/services/api/api_food.dart';
import 'package:untare/services/api/api_shopping_list.dart';

import 'package:untare/utils.dart';

class RecipeShoppingListWidget extends StatefulWidget {
final Recipe recipe;
final BuildContext btsContext;
Expand Down Expand Up @@ -224,27 +224,6 @@ class RecipeShoppingListWidgetState extends State<RecipeShoppingListWidget> {
bool? useFractions = (settingsCubit.state.userServerSetting!.useFractions == true);

double rawAmount = ingredient.amount * newServing / initServing;
String amount = (ingredient.amount > 0) ? ('${rawAmount.toFormattedString()} ') : '';
if (amount != '' && useFractions == true && (rawAmount % 1) != 0) {
// If we have a complex decimal we build a "simple" fraction. Otherwise we do the normal one
if ((((rawAmount - rawAmount.toInt()) * 100) % 5) != 0) {
// Use this crap because we can't change precision programmatically
if (rawAmount.toInt() < 1) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-1).reduce()} ';
} else if (rawAmount.toInt() < 10) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-2).reduce()} ';
} else if (rawAmount.toInt() < 100) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-3).reduce()} ';
} else if(rawAmount.toInt() < 1000) {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-4).reduce()} ';
} else {
amount = '${MixedFraction.fromDouble(rawAmount, precision: 1.0e-5).reduce()} ';
}
} else {
amount = '${MixedFraction.fromDouble(rawAmount)} ';
}
}

String unit = (ingredient.unit != null && ingredient.amount > 0) ? ('${ingredient.unit!.getUnitName(rawAmount)} ') : '';
String food = (ingredient.food != null) ? ('${ingredient.food!.getFoodName(rawAmount)} ') : '';
bool? checkBoxValue = !(ingredient.food != null && ingredient.food!.onHand!);
Expand Down Expand Up @@ -292,7 +271,7 @@ class RecipeShoppingListWidgetState extends State<RecipeShoppingListWidget> {
),
title: Wrap(
children: [
Text(amount, style: const TextStyle(fontWeight: FontWeight.bold)),
amountWrap(rawAmount, useFractions),
Text(unit, style: const TextStyle(fontWeight: FontWeight.bold)),
Text(food),
],
Expand Down
10 changes: 7 additions & 3 deletions lib/components/widgets/recipe_upsert_steps_stateful_widget.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:untare/components/dialogs/upsert_recipe_ingredient_dialog.dart';
import 'package:untare/extensions/double_extension.dart';
import 'package:untare/cubits/settings_cubit.dart';
import 'package:untare/models/ingredient.dart';
import 'package:untare/models/recipe.dart';
import 'package:untare/models/step.dart';
import 'package:untare/utils.dart';
import 'package:drag_and_drop_lists/drag_and_drop_lists.dart';
import 'package:flutter_gen/gen_l10n/app_locales.dart';

Expand Down Expand Up @@ -254,7 +256,9 @@ class RecipeUpsertStepsWidgetState extends State<RecipeUpsertStepsWidget> {

Widget buildIngredient(Ingredient ingredient, int stepIndex, int ingredientIndex) {
// Build ingredient text layout
String amount = (ingredient.amount > 0) ? ('${ingredient.amount.toFormattedString()} ') : '';
SettingsCubit settingsCubit = context.read<SettingsCubit>();
bool? useFractions = (settingsCubit.state.userServerSetting!.useFractions == true);

String unit = (ingredient.unit != null) ? ('${ingredient.unit!.name} ') : '';
String food = (ingredient.food != null) ? ('${ingredient.food!.name} ') : '';
String note = (ingredient.note != null && ingredient.note != '') ? ('(${ingredient.note !})') : '';
Expand Down Expand Up @@ -304,7 +308,7 @@ class RecipeUpsertStepsWidgetState extends State<RecipeUpsertStepsWidget> {
contentPadding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
title: Wrap(
children: [
Text(amount, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
amountWrap(ingredient.amount, useFractions),
Text(unit, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
Text(food, style: const TextStyle(fontSize: 15)),
Text(
Expand Down
9 changes: 6 additions & 3 deletions lib/pages/recipe_upsert_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ import 'package:untare/blocs/recipe/recipe_state.dart';
import 'package:untare/components/dialogs/upsert_recipe_ingredient_dialog.dart';
import 'package:untare/components/loading_component.dart';
import 'package:untare/components/recipes/recipe_image_component.dart';
import 'package:untare/extensions/double_extension.dart';
import 'package:untare/cubits/settings_cubit.dart';
import 'package:untare/futures/future_api_cache_keywords.dart';
import 'package:untare/models/ingredient.dart';
import 'package:untare/models/keyword.dart';
import 'package:untare/models/recipe.dart';
import 'package:untare/utils.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:untare/models/step.dart';
import 'package:untare/pages/recipe_detail_page.dart';
Expand Down Expand Up @@ -777,7 +778,9 @@ class RecipeUpsertPageState extends State<RecipeUpsertPage> {

Widget buildIngredient(Ingredient ingredient, int stepIndex, int ingredientIndex) {
// Build ingredient text layout
String amount = (ingredient.amount > 0) ? ('${ingredient.amount.toFormattedString()} ') : '';
SettingsCubit settingsCubit = context.read<SettingsCubit>();
bool? useFractions = (settingsCubit.state.userServerSetting!.useFractions == true);

String unit = (ingredient.amount > 0 && ingredient.unit != null) ? ('${ingredient.unit!.getUnitName(ingredient.amount)} ') : '';
String food = (ingredient.food != null) ? ('${ingredient.food!.getFoodName(ingredient.amount)} ') : '';
String note = (ingredient.note != null && ingredient.note != '') ? ('(${ingredient.note !})') : '';
Expand Down Expand Up @@ -828,7 +831,7 @@ class RecipeUpsertPageState extends State<RecipeUpsertPage> {
contentPadding: const EdgeInsets.fromLTRB(5, 0, 5, 0),
title: Wrap(
children: [
Text(amount, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
amountWrap(ingredient.amount, useFractions),
Text(unit, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15)),
Text(food, style: const TextStyle(fontSize: 15)),
Text(
Expand Down
22 changes: 21 additions & 1 deletion lib/pages/shopping_list_page.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// ignore_for_file: avoid_function_literals_in_foreach_calls

import 'dart:async';
import 'dart:ui';

import 'package:configurable_expansion_tile_null_safety/configurable_expansion_tile_null_safety.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_locales.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:fraction/fraction.dart';
import 'package:untare/blocs/recipe/recipe_bloc.dart';
import 'package:untare/blocs/recipe/recipe_state.dart';
import 'package:untare/blocs/shopping_list/shopping_list_bloc.dart';
Expand Down Expand Up @@ -414,6 +416,9 @@ class ShoppingListPageState extends State<ShoppingListPage> with TickerProviderS
}

Widget buildShoppingListEntryWidget(ShoppingListEntry shoppingListEntry, {bool? grouped}) {
SettingsCubit settingsCubit = context.read<SettingsCubit>();
bool? useFractions = (settingsCubit.state.userServerSetting!.useFractions == true);

String amount = (shoppingListEntry.amount > 0) ? ('${shoppingListEntry.amount.toFormattedString()} ') : '';
String unit = (shoppingListEntry.amount > 0 && shoppingListEntry.unit != null) ? ('${shoppingListEntry.unit!.getUnitName(shoppingListEntry.amount)} ') : '';
String food = (shoppingListEntry.food != null) ? (shoppingListEntry.food!.getFoodName(shoppingListEntry.amount)) : '';
Expand Down Expand Up @@ -473,7 +478,22 @@ class ShoppingListPageState extends State<ShoppingListPage> with TickerProviderS
RichText(
text: TextSpan(
children: [
TextSpan(text: amount, style: TextStyle(color: Theme.of(context).primaryTextTheme.bodyText1!.color, fontWeight: FontWeight.bold)),
TextSpan(
children: (useFractions == false || shoppingListEntry.amount % 1 == 0)
? [TextSpan(text: amount)]
: [
TextSpan(
text: '${shoppingListEntry.amount.toInt()} ',
),
TextSpan(
text:
'${MixedFraction.fromDouble(shoppingListEntry.amount % 1).reduce()} ',
style: const TextStyle(
fontFeatures: <FontFeature>[FontFeature.fractions()]))
],
style: TextStyle(
color: Theme.of(context).primaryTextTheme.bodyText1!.color,
fontWeight: FontWeight.bold)),
TextSpan(text: unit, style: TextStyle(color: Theme.of(context).primaryTextTheme.bodyText1!.color, fontWeight: FontWeight.bold)),
TextSpan(text: food, style: TextStyle(color: Theme.of(context).primaryTextTheme.bodyText1!.color)),
],
Expand Down
66 changes: 66 additions & 0 deletions lib/utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:fraction/fraction.dart';
import 'package:untare/extensions/double_extension.dart';

String doubleToFractionString(double rawAmount) {
// If we have a complex decimal we build a "simple" fraction. Otherwise we do the normal one
if ((((rawAmount % 1) * 100) % 5) != 0) {
// Use this crap because we can't change precision programmatically
if (rawAmount.toInt() < 1) {
return '${MixedFraction.fromDouble(rawAmount % 1, precision: 1.0e-1).reduce()} ';
} else if (rawAmount.toInt() < 10) {
return '${MixedFraction.fromDouble(rawAmount % 1, precision: 1.0e-2).reduce()} ';
} else if (rawAmount.toInt() < 100) {
return '${MixedFraction.fromDouble(rawAmount % 1, precision: 1.0e-3).reduce()} ';
} else if (rawAmount.toInt() < 1000) {
return '${MixedFraction.fromDouble(rawAmount % 1, precision: 1.0e-4).reduce()} ';
} else {
return '${MixedFraction.fromDouble(rawAmount % 1, precision: 1.0e-5).reduce()} ';
}
} else {
return '${MixedFraction.fromDouble(rawAmount % 1)} ';
}
}

Wrap amountWrap(double rawAmount, bool useFractions) {
List<Widget> child = [];

if (rawAmount == 0) {
// nothing to do
return Wrap();
}

if (useFractions == true && (rawAmount % 1) != 0) {
if (rawAmount >= 1.0) {
child.add(Text(
'${rawAmount.toInt().toString()} ',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
));
}
child.add(Text(
'${doubleToFractionString(rawAmount % 1)} ',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
fontFeatures: <FontFeature>[FontFeature.fractions()],
),
));
} else {
child.add(Text(
'${rawAmount.toFormattedString()} ',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
),
));
}

return Wrap(
children: child,
);
}