diff --git a/.github/ISSUE_TEMPLATE/1_bug.md b/.github/ISSUE_TEMPLATE/1_bug.md deleted file mode 100644 index e12f7506..00000000 --- a/.github/ISSUE_TEMPLATE/1_bug.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: I found a problem with wger -about: While using wger the application crashes or throws an exception, a - widget is buggy, or something looks wrong. -title: '' -labels: '' -assignees: '' - ---- - -## Steps to Reproduce - - - -1. ... -2. ... -3. ... - -**Expected results:** - -**Actual results:** - -
- Logs - - - -``` -``` - - -
diff --git a/.github/ISSUE_TEMPLATE/1_bug.yml b/.github/ISSUE_TEMPLATE/1_bug.yml new file mode 100644 index 00000000..385e5cc8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1_bug.yml @@ -0,0 +1,53 @@ +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema + +name: Bug report +description: Report an error or unexpected behavior +type: bug +body: + - type: dropdown + id: priority + attributes: + label: Priority/Impact + description: How severe is the issue? + options: + - Low (minor inconvenience) + - Medium (affects some functionality) + - High (critical issue, blocks workflow) + + - type: textarea + id: description + attributes: + label: Description + description: | + A clear and concise description of the bug. + placeholder: | + Please include any information you think is relevant to the issue you are experiencing. + This could include any steps to reproduce it (if it happens consistently), expected vs. + actual behavior, logs, screenshots, links to related issues, etc. + validations: + required: true + + - type: input + id: server-version + attributes: + label: Server version + description: | + What version of wger are you using and how did you install it (you use our server, + docker compose, manual installation, etc)? + placeholder: | + Check https:///software/about-us or the git sha1 of the last commit you pulled + validations: + required: false + + - type: input + id: app-version + attributes: + label: Mobile app version + description: | + What version of the mobile app are you using and how did you install it + (Play Store, App Store, Flathub, self compiled, etc.)? + placeholder: | + Check the "about wger" dialog + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/2_feature_request.md b/.github/ISSUE_TEMPLATE/2_feature_request.md deleted file mode 100644 index 924b1e42..00000000 --- a/.github/ISSUE_TEMPLATE/2_feature_request.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Feature request -about: Suggest a new idea for wger. -title: '' -labels: '' -assignees: '' - ---- - -## Use case - - - -## Proposal - - diff --git a/.github/ISSUE_TEMPLATE/2_feature_request.yml b/.github/ISSUE_TEMPLATE/2_feature_request.yml new file mode 100644 index 00000000..5ea0dff8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2_feature_request.yml @@ -0,0 +1,33 @@ +name: Feature request +description: Suggest a new idea for wger +type: enhancement +body: + - type: textarea + id: description + attributes: + label: Use case + description: | + A description of what new feature or behavior you would like to see. + validations: + required: true + + - type: textarea + id: proposal + attributes: + label: Proposal + description: | + Why is this feature needed? What problems does it solve? + validations: + required: false + + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: | + Any extra details, related issues, or mockups + placeholder: | + Screenshots or mockups, links to similar features in other applications, or other relevant + information. + validations: + required: false diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4cf8375a..75aef5cc 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,10 +1,11 @@ ## Description (Proposed Changes) + (Please try to mention in bullet points.) - - -## Link to the issue : +## Link to the issue : (Add link of the issue you have proposed changes to) @@ -16,9 +17,11 @@ Please make sure to add tests when implementing new features. ## Checklist -Please check that the PR fulfills all requirements listed below by checking the relevant checkboxes (`[x]`). This will ensure a smooth and quick review process. +Please check that the PR fulfills all requirements listed below by checking the relevant +checkboxes (`[x]`). This will ensure a smooth and quick review process. - [ ] Set a 100 character limit in your editor/IDE to avoid white space diffs in the PR + (run `dart format --line-length=100 .`) - [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Added yourself to AUTHORS.md - [ ] Updated/added relevant documentation (doc comments with `///`). diff --git a/AUTHORS.md b/AUTHORS.md index 18099e9a..ff5b442f 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -22,6 +22,7 @@ - Miroslav Mazel - - artchiee - - Tejas Bir Singh - +- Youssef Ahmed - - Abhishek Saini - - Hanaa Allohibi - - Shey Alnasrawi - @@ -34,6 +35,7 @@ - Xianglin Zeng - - Sangharsh Sulke - - Yashas H Majmudar - + ## Translators - Saudi Arabian diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ebcd78b2..08cbbe00 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -8,12 +8,12 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3845DFE0762714C6680D5DFA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFA44D9DB464FB85F130C5B5 /* Pods_Runner.framework */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; - C93895870C960E6C15E51713 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3017A465008DCA640E88319 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -30,15 +30,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0626AA66A7D8D715E41F96DC /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 0ED96167FF623FAB319C6E99 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 35EB2C4FBDA8631D02C34891 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 365AFD67D3A9053C371FE7D7 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 89F44165E15E0A7B109A05EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -46,7 +45,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D3017A465008DCA640E88319 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AFA44D9DB464FB85F130C5B5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C71BAD15819A771165D784B0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -54,17 +54,17 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C93895870C960E6C15E51713 /* Pods_Runner.framework in Frameworks */, + 3845DFE0762714C6680D5DFA /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 112D28FCA6DA9782BC706532 /* Frameworks */ = { + 23E168F95D2790D29E207E68 /* Frameworks */ = { isa = PBXGroup; children = ( - D3017A465008DCA640E88319 /* Pods_Runner.framework */, + AFA44D9DB464FB85F130C5B5 /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; @@ -87,7 +87,7 @@ 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, BB0286322FD60C00014F981C /* Pods */, - 112D28FCA6DA9782BC706532 /* Frameworks */, + 23E168F95D2790D29E207E68 /* Frameworks */, ); sourceTree = ""; }; @@ -117,9 +117,9 @@ BB0286322FD60C00014F981C /* Pods */ = { isa = PBXGroup; children = ( - 35EB2C4FBDA8631D02C34891 /* Pods-Runner.debug.xcconfig */, - 365AFD67D3A9053C371FE7D7 /* Pods-Runner.release.xcconfig */, - 0626AA66A7D8D715E41F96DC /* Pods-Runner.profile.xcconfig */, + C71BAD15819A771165D784B0 /* Pods-Runner.debug.xcconfig */, + 0ED96167FF623FAB319C6E99 /* Pods-Runner.release.xcconfig */, + 89F44165E15E0A7B109A05EB /* Pods-Runner.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -131,14 +131,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 67856A6BBEDCADB77EED5ED0 /* [CP] Check Pods Manifest.lock */, + 49A79EC3F389C902853B9186 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 2D55FD71E7AF35D39D861B93 /* [CP] Embed Pods Frameworks */, + 0A9E38C31DF3DC192213822E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -197,7 +197,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2D55FD71E7AF35D39D861B93 /* [CP] Embed Pods Frameworks */ = { + 0A9E38C31DF3DC192213822E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -230,7 +230,7 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 67856A6BBEDCADB77EED5ED0 /* [CP] Check Pods Manifest.lock */ = { + 49A79EC3F389C902853B9186 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( diff --git a/lib/helpers/misc.dart b/lib/helpers/misc.dart index 97027392..8db74a85 100644 --- a/lib/helpers/misc.dart +++ b/lib/helpers/misc.dart @@ -28,7 +28,7 @@ String repText( RepetitionUnit? repetitionUnitObj, num? weight, WeightUnit? weightUnitObj, - String? rir, + num? rir, ) { // TODO(x): how to (easily?) translate strings like the units or 'RiR' diff --git a/lib/models/workouts/log.dart b/lib/models/workouts/log.dart index 7744b280..c3082bf4 100644 --- a/lib/models/workouts/log.dart +++ b/lib/models/workouts/log.dart @@ -49,11 +49,11 @@ class Log { @JsonKey(required: true, name: 'slot_entry') int? slotEntryId; - @JsonKey(required: false) - String? rir; + @JsonKey(required: false, fromJson: stringToNum) + num? rir; - @JsonKey(required: false, name: 'rir_target') - String? rirTarget; + @JsonKey(required: false, fromJson: stringToNum, name: 'rir_target') + num? rirTarget; @JsonKey(required: true, fromJson: stringToNum, name: 'repetitions') num? repetitions; @@ -121,10 +121,6 @@ class Log { repetitionsUnitId = repetitionUnit?.id; } - void setRir(String rir) { - this.rir = rir; - } - /// Returns the text representation for a single setting, used in the gym mode String get singleLogRepTextNoNl { return repText(repetitions, repetitionsUnitObj, weight, weightUnitObj, rir) diff --git a/lib/models/workouts/log.g.dart b/lib/models/workouts/log.g.dart index d26477a0..397df1b5 100644 --- a/lib/models/workouts/log.g.dart +++ b/lib/models/workouts/log.g.dart @@ -34,8 +34,8 @@ Log _$LogFromJson(Map json) { repetitions: stringToNum(json['repetitions'] as String?), repetitionsTarget: stringToNum(json['repetitions_target'] as String?), repetitionsUnitId: (json['repetitions_unit'] as num?)?.toInt() ?? REP_UNIT_REPETITIONS_ID, - rir: json['rir'] as String?, - rirTarget: json['rir_target'] as String?, + rir: stringToNum(json['rir'] as String?), + rirTarget: stringToNum(json['rir_target'] as String?), weight: stringToNum(json['weight'] as String?), weightTarget: stringToNum(json['weight_target'] as String?), weightUnitId: (json['weight_unit'] as num?)?.toInt() ?? WEIGHT_UNIT_KG, diff --git a/lib/models/workouts/set_config_data.dart b/lib/models/workouts/set_config_data.dart index 97d2f711..3bc0f85a 100644 --- a/lib/models/workouts/set_config_data.dart +++ b/lib/models/workouts/set_config_data.dart @@ -78,14 +78,14 @@ class SetConfigData { @JsonKey(required: true, name: 'repetitions_rounding', fromJson: stringToNumNull) late num? repetitionsRounding; - @JsonKey(required: true) - late String? rir; + @JsonKey(required: true, fromJson: stringToNumNull) + late num? rir; - @JsonKey(required: true, name: 'max_rir') - late String? maxRir; + @JsonKey(required: true, name: 'max_rir', fromJson: stringToNumNull) + late num? maxRir; @JsonKey(required: true) - late String? rpe; + late num? rpe; @JsonKey(required: true, name: 'rest', fromJson: stringToNumNull) late num? restTime; diff --git a/lib/models/workouts/set_config_data.g.dart b/lib/models/workouts/set_config_data.g.dart index f1239905..561fd77b 100644 --- a/lib/models/workouts/set_config_data.g.dart +++ b/lib/models/workouts/set_config_data.g.dart @@ -50,9 +50,9 @@ SetConfigData _$SetConfigDataFromJson(Map json) { repetitionsRounding: json['repetitions_rounding'] == null ? 1 : stringToNumNull(json['repetitions_rounding'] as String?), - rir: json['rir'] as String?, - maxRir: json['max_rir'] as String?, - rpe: json['rpe'] as String?, + rir: stringToNumNull(json['rir'] as String?), + maxRir: stringToNumNull(json['max_rir'] as String?), + rpe: json['rpe'] as num?, restTime: stringToNumNull(json['rest'] as String?), maxRestTime: stringToNumNull(json['max_rest'] as String?), comment: json['comment'] as String? ?? '', diff --git a/lib/widgets/exercises/exercises.dart b/lib/widgets/exercises/exercises.dart index f07d162a..25e58bf2 100644 --- a/lib/widgets/exercises/exercises.dart +++ b/lib/widgets/exercises/exercises.dart @@ -193,7 +193,10 @@ class ExerciseDetail extends StatelessWidget { // TODO: add carousel for the other images final List out = []; if (_exercise.getMainImage != null) { - out.add(ExerciseImageWidget(image: _exercise.getMainImage)); + out.add(ExerciseImageWidget( + image: _exercise.getMainImage, + height: 250, + )); out.add(const SizedBox(height: PADDING)); } @@ -346,7 +349,7 @@ class MuscleWidget extends StatelessWidget { children: [ SvgPicture.asset('assets/images/muscles/$background.svg'), ...muscles.map((m) => SvgPicture.asset('assets/images/muscles/main/muscle-${m.id}.svg')), - ...musclesSecondary.map((m) => SvgPicture.asset( + ...musclesSecondary.where((m) => !muscles.contains(m)).map((m) => SvgPicture.asset( 'assets/images/muscles/secondary/muscle-${m.id}.svg', )), ], diff --git a/lib/widgets/exercises/filter_modal.dart b/lib/widgets/exercises/filter_modal.dart index 9ac88ad0..eb6758c7 100644 --- a/lib/widgets/exercises/filter_modal.dart +++ b/lib/widgets/exercises/filter_modal.dart @@ -48,7 +48,7 @@ class _ExerciseFilterModalBodyState extends State { dividerColor: Colors.transparent, expansionCallback: (panelIndex, isExpanded) { setState(() { - filters.filterCategories[panelIndex].isExpanded = !isExpanded; + filters.filterCategories[panelIndex].isExpanded = isExpanded; }); }, elevation: 0, diff --git a/lib/widgets/exercises/images.dart b/lib/widgets/exercises/images.dart index eb7f3e0f..ff590814 100644 --- a/lib/widgets/exercises/images.dart +++ b/lib/widgets/exercises/images.dart @@ -20,9 +20,10 @@ import 'package:flutter/widgets.dart'; import 'package:wger/models/exercises/image.dart'; class ExerciseImageWidget extends StatelessWidget { - const ExerciseImageWidget({this.image}); + const ExerciseImageWidget({this.image, this.height}); final ExerciseImage? image; + final double? height; @override Widget build(BuildContext context) { @@ -32,6 +33,7 @@ class ExerciseImageWidget extends StatelessWidget { image: NetworkImage(image!.url), fit: BoxFit.cover, imageSemanticLabel: 'Exercise image', + height: height, ) : const Image( image: AssetImage('assets/images/placeholder.png'), diff --git a/lib/widgets/routines/gym_mode/exercise_overview.dart b/lib/widgets/routines/gym_mode/exercise_overview.dart index 1d71102f..c4c25615 100644 --- a/lib/widgets/routines/gym_mode/exercise_overview.dart +++ b/lib/widgets/routines/gym_mode/exercise_overview.dart @@ -16,21 +16,19 @@ * along with this program. If not, see . */ import 'package:flutter/material.dart'; -import 'package:flutter_html/flutter_html.dart'; -import 'package:wger/helpers/i18n.dart'; import 'package:wger/models/exercises/exercise.dart'; -import 'package:wger/widgets/exercises/images.dart'; +import 'package:wger/widgets/exercises/exercises.dart'; import 'package:wger/widgets/routines/gym_mode/navigation.dart'; class ExerciseOverview extends StatelessWidget { final PageController _controller; - final Exercise _exerciseBase; + final Exercise _exercise; final double _ratioCompleted; final Map _exercisePages; const ExerciseOverview( this._controller, - this._exerciseBase, + this._exercise, this._ratioCompleted, this._exercisePages, ); @@ -40,43 +38,17 @@ class ExerciseOverview extends StatelessWidget { return Column( children: [ NavigationHeader( - _exerciseBase.getTranslation(Localizations.localeOf(context).languageCode).name, + _exercise.getTranslation(Localizations.localeOf(context).languageCode).name, _controller, exercisePages: _exercisePages, ), const Divider(), Expanded( - child: ListView( - padding: const EdgeInsets.symmetric(horizontal: 15), - children: [ - Text( - getTranslation(_exerciseBase.category!.name, context), - semanticsLabel: getTranslation(_exerciseBase.category!.name, context), - style: Theme.of(context).textTheme.titleLarge, - textAlign: TextAlign.center, - ), - ..._exerciseBase.equipment.map((e) => Text( - getTranslation(e.name, context), - style: Theme.of(context).textTheme.titleLarge, - textAlign: TextAlign.center, - )), - if (_exerciseBase.images.isNotEmpty) - SizedBox( - width: double.infinity, - height: 200, - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - ..._exerciseBase.images.map((e) => ExerciseImageWidget(image: e)), - ], - ), - ), - Html( - data: _exerciseBase - .getTranslation(Localizations.localeOf(context).languageCode) - .description, - ), - ], + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: ExerciseDetail(_exercise), + ), ), ), NavigationFooter(_controller, _ratioCompleted), diff --git a/lib/widgets/routines/gym_mode/log_page.dart b/lib/widgets/routines/gym_mode/log_page.dart index 0471eb90..1c9b966e 100644 --- a/lib/widgets/routines/gym_mode/log_page.dart +++ b/lib/widgets/routines/gym_mode/log_page.dart @@ -274,7 +274,7 @@ class _LogPageState extends State { ), if (_detailed) RiRInputWidget( - widget._log.rir == null ? null : num.parse(widget._log.rir!), + widget._log.rir, onChanged: (v) => {}, ), SwitchListTile( diff --git a/test/fixtures/routines/routine_logs.json b/test/fixtures/routines/routine_logs.json index cca04829..1835cc3d 100644 --- a/test/fixtures/routines/routine_logs.json +++ b/test/fixtures/routines/routine_logs.json @@ -161,7 +161,7 @@ "weight": "90.00", "weight_target": "80.00", "rir": "0.5", - "rir_target": null, + "rir_target": "0.5", "rest": 121, "rest_target": 120 }, diff --git a/test/workout/goldens/routine_logs_screen_detail.png b/test/workout/goldens/routine_logs_screen_detail.png index 0af52b65..f98c3912 100644 Binary files a/test/workout/goldens/routine_logs_screen_detail.png and b/test/workout/goldens/routine_logs_screen_detail.png differ diff --git a/test/workout/gym_mode_screen_test.dart b/test/workout/gym_mode_screen_test.dart index f20df62c..6c420890 100644 --- a/test/workout/gym_mode_screen_test.dart +++ b/test/workout/gym_mode_screen_test.dart @@ -86,6 +86,10 @@ void main() { testWidgets('Test the widgets on the gym mode screen', (WidgetTester tester) async { when(mockExerciseProvider.findExerciseById(1)).thenReturn(testExercises[0]); when(mockExerciseProvider.findExerciseById(6)).thenReturn(testExercises[5]); + when(mockExerciseProvider.findExercisesByVariationId( + null, + exerciseIdToExclude: anyNamed('exerciseIdToExclude'), + )).thenReturn([]); await tester.pumpWidget(renderGymMode()); await tester.tap(find.byType(TextButton)); diff --git a/test/workout/workout_log_model_test.dart b/test/workout/workout_log_model_test.dart index 9bfdfe93..1d993b2d 100644 --- a/test/workout/workout_log_model_test.dart +++ b/test/workout/workout_log_model_test.dart @@ -32,7 +32,7 @@ void main() { routineId: 100, exerciseId: 1, repetitions: 10, - rir: '1.5', + rir: 1.5, repetitionsUnitId: 1, weight: 20, weightUnitId: 1, @@ -45,7 +45,7 @@ void main() { routineId: 42, exerciseId: 1, repetitions: 10, - rir: '1.5', + rir: 1.5, repetitionsUnitId: 1, weight: 20, weightUnitId: 1, diff --git a/test_data/routines.dart b/test_data/routines.dart index 6885ce64..eb3efb75 100644 --- a/test_data/routines.dart +++ b/test_data/routines.dart @@ -50,7 +50,7 @@ Routine getTestRoutine({List? exercises}) { ..iteration = 2 ..slotEntryId = 3 ..weight = 10 - ..rir = '1.5' + ..rir = 1.5 ..date = DateTime(2021, 5, 1) ..repetitions = 10 ..routineId = 1; @@ -63,7 +63,7 @@ Routine getTestRoutine({List? exercises}) { ..iteration = 4 ..slotEntryId = 1 ..weight = 10 - ..rir = '2' + ..rir = 2 ..date = DateTime(2021, 5, 1) ..repetitions = 12 ..routineId = 1; @@ -76,7 +76,7 @@ Routine getTestRoutine({List? exercises}) { ..iteration = 5 ..slotEntryId = 1 ..weight = 50 - ..rir = '' + ..rir = null ..date = DateTime(2021, 5, 2) ..repetitions = 8 ..routineId = 1; @@ -248,8 +248,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '3x100kg', ), SetConfigData( @@ -262,8 +262,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '3x100kg', ), SetConfigData( @@ -276,8 +276,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '3x100kg', ), ], @@ -297,8 +297,8 @@ Routine getTestRoutine({List? exercises}) { weight: 10, weightUnit: testWeightUnit1, restTime: null, - rir: '', - rpe: '', + rir: null, + rpe: null, textRepr: '12x10kg', ), SetConfigData( @@ -311,8 +311,8 @@ Routine getTestRoutine({List? exercises}) { weight: 10, weightUnit: testWeightUnit1, restTime: null, - rir: '', - rpe: '', + rir: null, + rpe: null, textRepr: '12x10kg', ), SetConfigData( @@ -325,8 +325,8 @@ Routine getTestRoutine({List? exercises}) { weight: 10, weightUnit: testWeightUnit1, restTime: null, - rir: '', - rpe: '', + rir: null, + rpe: null, textRepr: '12x10kg', ), ], @@ -354,8 +354,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '3x100kg', ), SetConfigData( @@ -368,8 +368,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '3x100kg', ), SetConfigData( @@ -382,8 +382,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '3x100kg', ), ], @@ -414,8 +414,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '4 sets 3x100kg', ), ], @@ -435,8 +435,8 @@ Routine getTestRoutine({List? exercises}) { weight: 10, weightUnit: testWeightUnit1, restTime: 60, - rir: '', - rpe: '', + rir: null, + rpe: null, textRepr: '4 sets 12x10kg', ), ], @@ -464,8 +464,8 @@ Routine getTestRoutine({List? exercises}) { weight: 100, weightUnit: testWeightUnit1, restTime: 120, - rir: '1.5', - rpe: '8', + rir: 1.5, + rpe: 8, textRepr: '4 sets 3x100kg', ), ],