Merge branch 'master' into yhm/issue-724

# Conflicts:
#	AUTHORS.md
#	ios/Runner.xcodeproj/project.pbxproj
This commit is contained in:
Yashas H Majmudar
2025-03-26 18:45:56 -04:00
22 changed files with 177 additions and 169 deletions

View File

@@ -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'

View File

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

View File

@@ -34,8 +34,8 @@ Log _$LogFromJson(Map<String, dynamic> 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,

View File

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

View File

@@ -50,9 +50,9 @@ SetConfigData _$SetConfigDataFromJson(Map<String, dynamic> 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? ?? '',

View File

@@ -193,7 +193,10 @@ class ExerciseDetail extends StatelessWidget {
// TODO: add carousel for the other images
final List<Widget> 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',
)),
],

View File

@@ -48,7 +48,7 @@ class _ExerciseFilterModalBodyState extends State<ExerciseFilterModalBody> {
dividerColor: Colors.transparent,
expansionCallback: (panelIndex, isExpanded) {
setState(() {
filters.filterCategories[panelIndex].isExpanded = !isExpanded;
filters.filterCategories[panelIndex].isExpanded = isExpanded;
});
},
elevation: 0,

View File

@@ -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'),

View File

@@ -16,21 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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<Exercise, int> _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),

View File

@@ -274,7 +274,7 @@ class _LogPageState extends State<LogPage> {
),
if (_detailed)
RiRInputWidget(
widget._log.rir == null ? null : num.parse(widget._log.rir!),
widget._log.rir,
onChanged: (v) => {},
),
SwitchListTile(