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

Plate 46 calc #688

Open
wants to merge 5 commits into
base: master
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
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Thilina Herath - <https://github.com/ThilinaTCH>
- Marko Milosevic - <https://github.com/TaarnStar>
- Karthik Reddy (Axel) - <https://github.com/AxelBlaz3>
- Ayush Sourav Jagaty - <https://github.com/AyushJagaty>
- Ogundoyin Toluwani - <https://github.com/Tolu007>
- Nenza Nurfirmansyah - <https://github.com/nenzan>
- Florian Schmitz - <https://github.com/floodoo>
Expand Down
2 changes: 1 addition & 1 deletion ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048

COCOAPODS: 1.16.0
COCOAPODS: 1.15.2
13 changes: 13 additions & 0 deletions lib/helpers/exercises/plate_configurator.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';

class PlateConfiguration extends ChangeNotifier {
//olympic standard weights
List<double> _plateWeights = [1.25, 2.5, 5, 10, 15, 20, 25];

List<double> get plateWeights => _plateWeights;

void setPlateWeights(List<double> weights) {
_plateWeights = weights;
notifyListeners();
}
}
2 changes: 1 addition & 1 deletion lib/helpers/gym_mode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/// Calculates the number of plates needed to reach a specific weight
List<num> plateCalculator(num totalWeight, num barWeight, List<num> plates) {
final List<num> ans = [];

print("total weight is $totalWeight");
// Weight is less than the bar
if (totalWeight < barWeight) {
return [];
Expand Down
5 changes: 3 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
Expand All @@ -27,6 +26,7 @@ import 'package:wger/providers/exercises.dart';
import 'package:wger/providers/gallery.dart';
import 'package:wger/providers/measurement.dart';
import 'package:wger/providers/nutrition.dart';
import 'package:wger/providers/plate_weights.dart';
import 'package:wger/providers/user.dart';
import 'package:wger/providers/workout_plans.dart';
import 'package:wger/screens/add_exercise_screen.dart';
Expand Down Expand Up @@ -57,7 +57,7 @@ import 'providers/auth.dart';

void main() async {
//zx.setLogEnabled(kDebugMode);

// Needs to be called before runApp
WidgetsFlutterBinding.ensureInitialized();

Expand All @@ -73,6 +73,7 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context)=> PlateWeights()),
ChangeNotifierProvider(create: (ctx) => AuthProvider()),
ChangeNotifierProxyProvider<AuthProvider, ExercisesProvider>(
create: (context) => ExercisesProvider(
Expand Down
70 changes: 70 additions & 0 deletions lib/providers/plate_weights.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:flutter/widgets.dart';
import 'package:wger/helpers/gym_mode.dart';

class PlateWeights extends ChangeNotifier{
String unitOfPlate = 'kg';
Copy link
Member

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"

bool flag = false;
Copy link
Member

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 ;)

num totalWeight = 0;
num barWeight = 20;
num convertTolbs = 2.205;
num totalWeightInKg = 0;
num barWeightInKg = 20;
List<num> selectedWeights = [];
List<num> kgWeights = [1.25, 2.5, 5, 10, 15, 20, 25];
List<num> lbsWeights = [2.5, 5, 10, 25, 35, 45];
List<num> customPlates = [];
late Map<num,int> grouped;

void unitChange() {
if(unitOfPlate=='lbs') {
totalWeight = totalWeightInKg;
unitOfPlate = 'kg';
barWeight = barWeightInKg;
} else {
unitOfPlate = 'lbs';
totalWeight = totalWeightInKg*2.205;
barWeight = barWeightInKg*2.205;
}
notifyListeners();
}

void toggleSelection(num x) {
Copy link
Member

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)

Copy link
Author

@AyushJagaty AyushJagaty Dec 22, 2024

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.

declared_in_main
flutter 2
Untitled 3

Screen.Recording.2024-12-22.at.4.36.30.PM.mov

Copy link
Member

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!

if(unitOfPlate == 'kg') {
if(selectedWeights.contains(x)) {
selectedWeights.remove(x);
} else {
selectedWeights.add(x);
}
} else {
Copy link
Member

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.

if(selectedWeights.contains(x)) {
selectedWeights.remove(x);
} else {
selectedWeights.add(x);
}
}
notifyListeners();
}

void clear() {
selectedWeights.clear();
notifyListeners();
}

void setWeight(num x) {
totalWeight = x;
totalWeightInKg=x;
notifyListeners();
}

void calculatePlates() {
selectedWeights.sort();
customPlates = plateCalculator(totalWeight,barWeight,selectedWeights);
grouped = groupPlates(customPlates);
notifyListeners();
}

void resetPlates() {
selectedWeights = [];
notifyListeners();
}
}
118 changes: 118 additions & 0 deletions lib/screens/add_plate_weights.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wger/providers/plate_weights.dart';

class AddPlateWeights extends StatefulWidget {
const AddPlateWeights({super.key});

@override
State<AddPlateWeights> createState() => _AddPlateWeightsState();
}

class _AddPlateWeightsState extends State<AddPlateWeights> {

@override
Widget build(BuildContext context) {
return Consumer<PlateWeights> (
builder:(context,plateProvider,child)=> Scaffold (
appBar: AppBar (
title: const Text('Enter Custom Plate Weights'),
Copy link
Member

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)

),
body: Column (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure there is enough margin on the right side of the screen as well (or wrap around if there's not enough space). Also I would name the dropdown something like "preferred unit". If you want, you can extract this info from the profile from the UserProvider (the isMetric).

Bildschirmfoto 2024-12-12 um 13 02 35

children: [
Row (
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Kg or lbs'),
DropdownButton (
onChanged: (newValue){
plateProvider.clear();
if((newValue!) != plateProvider.unitOfPlate) {
plateProvider.unitChange();
}
},
items: ['kg','lbs'].map((unit){
return DropdownMenuItem<String> (
value: unit,
child: Text(unit),
);
}).toList(),
),
],
),
SingleChildScrollView (
scrollDirection: Axis.horizontal,
child: Row (
children: plateProvider.unitOfPlate == 'kg'
Copy link
Member

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

? plateProvider.kgWeights.map((number) {
return GestureDetector(
onTap: () => plateProvider.toggleSelection(number),
child: Container (
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration (
color: plateProvider.selectedWeights.contains(number)
? const Color.fromARGB(255, 82, 226, 236)
Copy link
Member

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

: const Color.fromARGB(255, 97, 105, 101),
borderRadius: BorderRadius.circular(10),
),
child: Text (
'$number kg', // Add unit to text
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}).toList()
: plateProvider.lbsWeights.map((number) {
return GestureDetector(
onTap: () => plateProvider.toggleSelection(number),
child: Container(
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration (
color: plateProvider.selectedWeights.contains(number)
? const Color.fromARGB(255, 82, 226, 236)
: const Color.fromARGB(255, 97, 105, 101),
borderRadius: BorderRadius.circular(10),
),
child: Text (
'$number lbs', // Add unit to text
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
);
}).toList(),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: (){
if(plateProvider.selectedWeights.isNotEmpty){
plateProvider.flag=true;
plateProvider.calculatePlates();}
Navigator.pop(context);
},
child: const Text('Done'),
),
ElevatedButton(
onPressed: (){
plateProvider.resetPlates();
},
child: const Text('Reset',style: TextStyle(color: Colors.red,fontWeight: FontWeight.bold))
),
],
),
]
),
),
);
}
}
Loading
Loading