Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

90 feature request change kcal intake #145

Merged
merged 4 commits into from
Jan 26, 2025
Merged
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
33 changes: 33 additions & 0 deletions lib/core/data/data_source/config_data_source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,39 @@ class ConfigDataSource {
config?.save();
}

Future<double> getKcalAdjustment() async {
final config = _configBox.get(_configKey);
return config?.userKcalAdjustment ?? 0;
}

Future<void> setConfigKcalAdjustment(double kcalAdjustment) async {
_log.fine('Updating config kcalAdjustment to $kcalAdjustment');
final config = _configBox.get(_configKey);
config?.userKcalAdjustment = kcalAdjustment;
config?.save();
}

Future<void> setConfigCarbGoalPct(double carbGoalPct) async {
_log.fine('Updating config carbGoalPct to $carbGoalPct');
final config = _configBox.get(_configKey);
config?.userCarbGoalPct = carbGoalPct;
config?.save();
}

Future<void> setConfigProteinGoalPct(double proteinGoalPct) async {
_log.fine('Updating config proteinGoalPct to $proteinGoalPct');
final config = _configBox.get(_configKey);
config?.userProteinGoalPct = proteinGoalPct;
config?.save();
}

Future<void> setConfigFatGoalPct(double fatGoalPct) async {
_log.fine('Updating config fatGoalPct to $fatGoalPct');
final config = _configBox.get(_configKey);
config?.userFatGoalPct = fatGoalPct;
config?.save();
}

Future<ConfigDBO> getConfig() async {
return _configBox.get(_configKey) ?? ConfigDBO.empty();
}
Expand Down
10 changes: 9 additions & 1 deletion lib/core/data/dbo/config_dbo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,18 @@ class ConfigDBO extends HiveObject {
AppThemeDBO selectedAppTheme;
@HiveField(4)
bool? usesImperialUnits;
@HiveField(5)
double? userKcalAdjustment;
@HiveField(6)
double? userCarbGoalPct;
@HiveField(7)
double? userProteinGoalPct;
@HiveField(8)
double? userFatGoalPct;

ConfigDBO(this.hasAcceptedDisclaimer, this.hasAcceptedPolicy,
this.hasAcceptedSendAnonymousData, this.selectedAppTheme,
{this.usesImperialUnits = false});
{this.usesImperialUnits = false, this.userKcalAdjustment});

factory ConfigDBO.empty() =>
ConfigDBO(false, false, false, AppThemeDBO.system);
Expand Down
18 changes: 15 additions & 3 deletions lib/core/data/dbo/config_dbo.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions lib/core/data/repository/config_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,18 @@ class ConfigRepository {
Future<void> setConfigUsesImperialUnits(bool usesImperialUnits) async {
_configDataSource.setConfigUsesImperialUnits(usesImperialUnits);
}

Future<double> getConfigKcalAdjustment() async {
return await _configDataSource.getKcalAdjustment();
}

Future<void> setConfigKcalAdjustment(double kcalAdjustment) async {
_configDataSource.setConfigKcalAdjustment(kcalAdjustment);
}

Future<void> setUserMacroPct(double carbs, double protein, double fat) async {
_configDataSource.setConfigCarbGoalPct(carbs);
_configDataSource.setConfigProteinGoalPct(protein);
_configDataSource.setConfigFatGoalPct(fat);
}
}
20 changes: 18 additions & 2 deletions lib/core/domain/entity/config_entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,40 @@ class ConfigEntity extends Equatable {
final bool hasAcceptedSendAnonymousData;
final AppThemeEntity appTheme;
final bool usesImperialUnits;
final double? userKcalAdjustment;
final double? userCarbGoalPct;
final double? userProteinGoalPct;
final double? userFatGoalPct;

const ConfigEntity(this.hasAcceptedDisclaimer, this.hasAcceptedPolicy,
this.hasAcceptedSendAnonymousData, this.appTheme,
{this.usesImperialUnits = false});
{this.usesImperialUnits = false,
this.userKcalAdjustment,
this.userCarbGoalPct,
this.userProteinGoalPct,
this.userFatGoalPct});

factory ConfigEntity.fromConfigDBO(ConfigDBO dbo) => ConfigEntity(
dbo.hasAcceptedDisclaimer,
dbo.hasAcceptedPolicy,
dbo.hasAcceptedSendAnonymousData,
AppThemeEntity.fromAppThemeDBO(dbo.selectedAppTheme),
usesImperialUnits: dbo.usesImperialUnits ?? false,
userKcalAdjustment: dbo.userKcalAdjustment,
userCarbGoalPct: dbo.userCarbGoalPct,
userProteinGoalPct: dbo.userProteinGoalPct,
userFatGoalPct: dbo.userFatGoalPct,
);

@override
List<Object?> get props => [
hasAcceptedDisclaimer,
hasAcceptedPolicy,
hasAcceptedSendAnonymousData,
usesImperialUnits
usesImperialUnits,
userKcalAdjustment,
userCarbGoalPct,
userProteinGoalPct,
userFatGoalPct,
];
}
9 changes: 9 additions & 0 deletions lib/core/domain/usecase/add_config_usecase.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,13 @@ class AddConfigUsecase {
Future<void> setConfigUsesImperialUnits(bool usesImperialUnits) async {
_configRepository.setConfigUsesImperialUnits(usesImperialUnits);
}

Future<void> setConfigKcalAdjustment(double kcalAdjustment) async {
_configRepository.setConfigKcalAdjustment(kcalAdjustment);
}

Future<void> setConfigMacroGoalPct(
double carbGoalPct, double proteinGoalPct, double fatPctGoal) async {
_configRepository.setUserMacroPct(carbGoalPct, proteinGoalPct, fatPctGoal);
}
}
30 changes: 30 additions & 0 deletions lib/core/domain/usecase/get_kcal_goal_usecase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:collection/collection.dart';
import 'package:opennutritracker/core/data/repository/config_repository.dart';
import 'package:opennutritracker/core/data/repository/user_activity_repository.dart';
import 'package:opennutritracker/core/data/repository/user_repository.dart';
import 'package:opennutritracker/core/domain/entity/user_entity.dart';
import 'package:opennutritracker/core/utils/calc/calorie_goal_calc.dart';

class GetKcalGoalUsecase {
final UserRepository _userRepository;
final ConfigRepository _configRepository;
final UserActivityRepository _userActivityRepository;

GetKcalGoalUsecase(
this._userRepository, this._configRepository, this._userActivityRepository);

Future<double> getKcalGoal(
{UserEntity? userEntity,
double? totalKcalActivitiesParam,
double? kcalUserAdjustment}) async {
final user = userEntity ?? await _userRepository.getUserData();
final config = await _configRepository.getConfig();
final totalKcalActivities = totalKcalActivitiesParam ??
(await _userActivityRepository.getAllUserActivityByDate(DateTime.now()))
.map((activity) => activity.burnedKcal)
.toList()
.sum;
return CalorieGoalCalc.getTotalKcalGoal(user, totalKcalActivities,
kcalUserAdjustment: config.userKcalAdjustment);
}
}
32 changes: 32 additions & 0 deletions lib/core/domain/usecase/get_macro_goal_usecase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:opennutritracker/core/data/repository/config_repository.dart';
import 'package:opennutritracker/core/utils/calc/macro_calc.dart';

class GetMacroGoalUsecase {
final ConfigRepository _configRepository;

GetMacroGoalUsecase(this._configRepository);

Future<double> getCarbsGoal(double totalCalorieGoal) async {
final config = await _configRepository.getConfig();
final userCarbGoal = config.userCarbGoalPct;

return MacroCalc.getTotalCarbsGoal(totalCalorieGoal,
userCarbsGoal: userCarbGoal);
}

Future<double> getFatsGoal(double totalCalorieGoal) async {
final config = await _configRepository.getConfig();
final userFatGoal = config.userFatGoalPct;

return MacroCalc.getTotalFatsGoal(totalCalorieGoal,
userFatsGoal: userFatGoal);
}

Future<double> getProteinsGoal(double totalCalorieGoal) async {
final config = await _configRepository.getConfig();
final userProteinGoal = config.userProteinGoalPct;

return MacroCalc.getTotalProteinsGoal(totalCalorieGoal,
userProteinsGoal: userProteinGoal);
}
}
4 changes: 3 additions & 1 deletion lib/core/utils/calc/calorie_goal_calc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ class CalorieGoalCalc {
TDEECalc.getTDEEKcalIOM2005(userEntity);

static double getTotalKcalGoal(
UserEntity userEntity, double totalKcalActivities) =>
UserEntity userEntity, double totalKcalActivities,
{double? kcalUserAdjustment}) =>
getTdee(userEntity) +
getKcalGoalAdjustment(userEntity.goal) +
(kcalUserAdjustment ?? 0) +
totalKcalActivities;

static double getKcalGoalAdjustment(UserWeightGoalEntity goal) {
Expand Down
25 changes: 19 additions & 6 deletions lib/core/utils/calc/macro_calc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,25 @@ class MacroCalc {
static const _defaultFatsPercentageGoal = 0.25;
static const _defaultProteinsPercentageGoal = 0.15;

static double getTotalCarbsGoal(double totalCalorieGoal) =>
(totalCalorieGoal * _defaultCarbsPercentageGoal) / _carbsKcalPerGram;
/// Calculate the total carbs goal based on the total calorie goal
/// Uses the default percentage if the user has not set a goal
static double getTotalCarbsGoal(
double totalCalorieGoal, {double? userCarbsGoal}) =>
(totalCalorieGoal * (userCarbsGoal ?? _defaultCarbsPercentageGoal)) /
_carbsKcalPerGram;

static double getTotalFatsGoal(double totalCalorieGoal) =>
(totalCalorieGoal * _defaultFatsPercentageGoal) / _fatKcalPerGram;
/// Calculate the total fats goal based on the total calorie goal
/// Uses the default percentage if the user has not set a goal
static double getTotalFatsGoal(
double totalCalorieGoal, {double? userFatsGoal}) =>
(totalCalorieGoal * (userFatsGoal ?? _defaultFatsPercentageGoal)) /
_fatKcalPerGram;

static double getTotalProteinsGoal(double totalCalorieGoal) =>
(totalCalorieGoal * _defaultProteinsPercentageGoal) / _proteinKcalPerGram;
/// Calculate the total proteins goal based on the total calorie goal
/// Uses the default percentage if the user has not set a goal
static double getTotalProteinsGoal(
double totalCalorieGoal, {double? userProteinsGoal}) =>
(totalCalorieGoal *
(userProteinsGoal ?? _defaultProteinsPercentageGoal)) /
_proteinKcalPerGram;
}
15 changes: 11 additions & 4 deletions lib/core/utils/locator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import 'package:opennutritracker/core/domain/usecase/delete_intake_usecase.dart'
import 'package:opennutritracker/core/domain/usecase/delete_user_activity_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_config_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_intake_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_kcal_goal_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_macro_goal_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_physical_activity_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_tracked_day_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_user_activity_usecase.dart';
Expand Down Expand Up @@ -84,21 +86,23 @@ Future<void> initLocator() async {
locator(),
locator(),
locator(),
locator(),
locator()));
locator.registerLazySingleton(() => DiaryBloc(locator(), locator()));
locator.registerLazySingleton(() => CalendarDayBloc(
locator(), locator(), locator(), locator(), locator(), locator()));
locator.registerLazySingleton<ProfileBloc>(
() => ProfileBloc(locator(), locator(), locator(), locator(), locator()));
locator.registerLazySingleton(() => SettingsBloc(locator(), locator()));
locator.registerLazySingleton(() =>
SettingsBloc(locator(), locator(), locator(), locator(), locator()));

locator.registerFactory<ActivitiesBloc>(() => ActivitiesBloc(locator()));
locator.registerFactory<RecentActivitiesBloc>(
() => RecentActivitiesBloc(locator()));
locator.registerFactory<ActivityDetailBloc>(
() => ActivityDetailBloc(locator(), locator(), locator()));
locator.registerFactory<ActivityDetailBloc>(() => ActivityDetailBloc(
locator(), locator(), locator(), locator(), locator()));
locator.registerFactory<MealDetailBloc>(
() => MealDetailBloc(locator(), locator(), locator()));
() => MealDetailBloc(locator(), locator(), locator(), locator()));
locator.registerFactory<ScannerBloc>(() => ScannerBloc(locator(), locator()));
locator.registerFactory<EditMealBloc>(() => EditMealBloc(locator()));
locator.registerFactory<AddMealBloc>(() => AddMealBloc(locator()));
Expand Down Expand Up @@ -140,6 +144,9 @@ Future<void> initLocator() async {
() => GetTrackedDayUsecase(locator()));
locator.registerLazySingleton<AddTrackedDayUsecase>(
() => AddTrackedDayUsecase(locator()));
locator.registerLazySingleton(
() => GetKcalGoalUsecase(locator(), locator(), locator()));
locator.registerLazySingleton(() => GetMacroGoalUsecase(locator()));

// Repositories
locator.registerLazySingleton(() => ConfigRepository(locator()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import 'package:opennutritracker/core/domain/entity/user_activity_entity.dart';
import 'package:opennutritracker/core/domain/entity/user_entity.dart';
import 'package:opennutritracker/core/domain/usecase/add_tracked_day_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/add_user_activity_usercase.dart';
import 'package:opennutritracker/core/domain/usecase/get_kcal_goal_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_macro_goal_usecase.dart';
import 'package:opennutritracker/core/domain/usecase/get_user_usecase.dart';
import 'package:opennutritracker/core/utils/calc/calorie_goal_calc.dart';
import 'package:opennutritracker/core/utils/calc/macro_calc.dart';
import 'package:opennutritracker/core/utils/calc/met_calc.dart';
import 'package:opennutritracker/core/utils/id_generator.dart';
Expand All @@ -21,9 +22,15 @@ class ActivityDetailBloc
final GetUserUsecase _getUserUsecase;
final AddUserActivityUsecase _addUserActivityUsecase;
final AddTrackedDayUsecase _addTrackedDayUsecase;
final GetKcalGoalUsecase _getKcalGoalUsecase;
final GetMacroGoalUsecase _getMacroGoalUsecase;

ActivityDetailBloc(this._getUserUsecase, this._addUserActivityUsecase,
this._addTrackedDayUsecase)
ActivityDetailBloc(
this._getUserUsecase,
this._addUserActivityUsecase,
this._addTrackedDayUsecase,
this._getKcalGoalUsecase,
this._getMacroGoalUsecase)
: super(ActivityDetailInitial()) {
on<LoadActivityDetailEvent>((event, emit) async {
emit(ActivityDetailLoadingState());
Expand Down Expand Up @@ -58,12 +65,13 @@ class ActivityDetailBloc
}

void _updateTrackedDay(DateTime dateTime, double caloriesBurned) async {
final userEntity = await _getUserUsecase.getUserData();
final totalKcalGoal =
CalorieGoalCalc.getTotalKcalGoal(userEntity, caloriesBurned);
final totalCarbsGoal = MacroCalc.getTotalCarbsGoal(totalKcalGoal);
final totalFatGoal = MacroCalc.getTotalFatsGoal(totalKcalGoal);
final totalProteinGoal = MacroCalc.getTotalProteinsGoal(totalKcalGoal);
final totalKcalGoal = await _getKcalGoalUsecase.getKcalGoal(
totalKcalActivitiesParam: caloriesBurned);
final totalCarbsGoal =
await _getMacroGoalUsecase.getCarbsGoal(totalKcalGoal);
final totalFatGoal = await _getMacroGoalUsecase.getFatsGoal(totalKcalGoal);
final totalProteinGoal =
await _getMacroGoalUsecase.getProteinsGoal(totalKcalGoal);

final hasTrackedDay =
await _addTrackedDayUsecase.hasTrackedDay(DateTime.now());
Expand Down
Loading
Loading