-
-
Notifications
You must be signed in to change notification settings - Fork 252
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
Plate 46 calc #688
base: master
Are you sure you want to change the base?
Plate 46 calc #688
Conversation
thanks for the PR, I'll review it next week |
lib/widgets/workouts/gym_mode.dart
Outdated
plateProvider.setWeight(num.parse(_weightController.text)); | ||
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>const AddPlateWeights())); | ||
}, | ||
child: const Text("Enter custom Denomination's") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make this a bit less prominent, a gear icon left to "Plates" would probably be enough
appBar: AppBar ( | ||
title: const Text('Enter Custom Plate Weights'), | ||
), | ||
body: Column ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/providers/plate_weights.dart
Outdated
notifyListeners(); | ||
} | ||
|
||
void toggleSelection(num x) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would save the selected weights to the device, then we don't need to add this every time. You can simply save the array to SharedPreferences (just dump it as a string and later read from that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am encountering difficulties in calculating plate denominations using the saved plate weight denominations while implementing shared preferences.
I've explored several approaches:
Async Function in initState(): I attempted to call an async function containing await loadFromSharedPref() within the initState() of my widget. However, this resulted in widget.getPlates executing before loadFromSharedPref(), leading to an empty list being displayed initially but it is being shown inside the slider selection menu.
Calling loadFromSharedPref() from main(): I tried calling loadFromSharedPref() from the main() function to ensure it executed before widget.getPlates. While this successfully loaded and printed the saved values in the main() function, the widget.getPlates still displayed an empty list but it is being shown inside the slider selection menu.
Flag in PlateWeightsProvider: I introduced a flag (loadedFromSharedPref) within the PlateWeightsProvider, setting it to true after loadFromSharedPref() completes. In widget.getPlates, I attempted to wait for the flag to become true before displaying the plate denominations. Unfortunately, this approach also failed to display the saved results correctly, and I'm now unable to select/deselect any options or reset them.
I've attached screenshots of the relevant functions for further clarity.
I would greatly appreciate any guidance or suggestions on how to effectively load and display shared preferences within my PlateWeightsProvider and ensure proper functionality within my widgets.
Screen.Recording.2024-12-22.at.4.36.30.PM.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mhh, hadn't thought this would cause problems. I'll take a look!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AyushJagaty I got this to work by calling the prefs loader on initstate on the widget (the method itself is also simpler than yours, I think we can get away with just catching some errors and returning an empty list)
in the provider
void readPlates() async {
final prefs = await SharedPreferences.getInstance();
final platePrefData = prefs.getString(PREFS_PLATES);
if (platePrefData != null) {
final plateData = json.decode(platePrefData);
selectedWeights = plateData.cast<num>();
}
notifyListeners();
}
Future<void> toggleSelection(num x) async {
...
final prefs = await SharedPreferences.getInstance();
final plateData = json.encode(selectedWeights);
prefs.setString(PREFS_PLATES, plateData);
}
in the plate widget:
class _AddPlateWeightsState extends State<AddPlateWeights> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
Provider.of<PlateWeights>(context, listen: false).readPlates();
});
}
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi wish you a very Happy New Year!!! I tried this approach and i had also tried a similar approach calling from the initstate(it was the first approach which i had mentioned in the previous message but it was more complex than yours .... thanks i could learn something new from your approach).
This approach also resulted in a similar situation resulting in widget getPlates executing before readPlates(), leading to display the denominations according to the default weights initially but the selected ones are being shown inside the slider selection menu. As in this approach it is being called from AddPlateWeights where as AddPlateWeights gets called when I tap on the gear icon(icon for selecting the available plates). I also tried calling from the initstate of _LogPageState of gym_mode.dart as we want to receive the result without tapping the gear icon but it resulted in the same situation(widget getPlates executing before readPlates(), leading to display the denominations according to the default weights initially but the selected ones are being shown inside the slider selection menu).
I had tried with both the readPlates provided code and with a modified readPlates function with catching some errors and returning an empty list -
void readPlates() async{
final pref = await SharedPreferences.getInstance();
final platePrefData = pref.getString('selectedPlates');
if(platePrefData != null){
try{
final plateData = json.decode(platePrefData);
if(plateData is List){
selectedWeights = plateData.cast<num>();
}else{
throw const FormatException('Not a List');
}
}catch(e){
selectedWeights = [];
}
}
print('loaded');
notifyListeners();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
happy new year to you too!! It's probably easier if you push the updated code and tell me what to do, I'm currently not sure what the problem is 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the trouble!! Have pushed the updated code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to let you know that I haven't forgotten about this, will take a look as soon as I can
lib/providers/plate_weights.dart
Outdated
|
||
class PlateWeights extends ChangeNotifier{ | ||
String unitOfPlate = 'kg'; | ||
bool flag = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does this do? Probably needs a better name ;)
lib/providers/plate_weights.dart
Outdated
} else { | ||
selectedWeights.add(x); | ||
} | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren't the if and else branches the same? :D
In this respect, I think the different variables could be simplified, e.g.having always totalWeight and totalWeightKg seems redundant.
lib/screens/add_plate_weights.dart
Outdated
return Consumer<PlateWeights> ( | ||
builder:(context,plateProvider,child)=> Scaffold ( | ||
appBar: AppBar ( | ||
title: const Text('Enter Custom Plate Weights'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps "Select available plates" would be better. Also, all user-facing strings should be translatable (this also applies for the buttons below, for those there should be already strings).
For this, just add the string to app_en.arb
and then you can just use them with AppLocalizations.of(context).<yourKey>;
(sometimes the IDE gets a bit confused or doesn't catch up immediately and you'll have to insert the import manually or it will mark the key as not existing, even if it does)
lib/screens/add_plate_weights.dart
Outdated
SingleChildScrollView ( | ||
scrollDirection: Axis.horizontal, | ||
child: Row ( | ||
children: plateProvider.unitOfPlate == 'kg' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both branches are basically the same, you can just do plateProvider.unitOfPlate == 'kg' ? '$number kg' : '$number lbs' within the Text widget
lib/screens/add_plate_weights.dart
Outdated
padding: const EdgeInsets.all(16), | ||
decoration: BoxDecoration ( | ||
color: plateProvider.selectedWeights.contains(number) | ||
? const Color.fromARGB(255, 82, 226, 236) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of hard coding a color, I would use something from the Theme, then this will also automatically work on the dark mode. There should be something in Theme.of(context).colorScheme
suitable for this
lib/providers/plate_weights.dart
Outdated
import 'package:wger/helpers/gym_mode.dart'; | ||
|
||
class PlateWeights extends ChangeNotifier{ | ||
String unitOfPlate = 'kg'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a boolean would be better here, something like isMetric, then we don't have to use magic strings in the code, which will avoid mistakes like e.g. writing "Lb"
Description (Proposed Changes)
-Allow users to input their preferred bar weight and available plate weights in both kilograms and pounds.
-Calculate the optimal plate combination for a given target weight, considering the user's custom bar and plate weights.
Link to the issue : #46