From 3dc951944504bd85d885ad898c40ca97bf3f16d1 Mon Sep 17 00:00:00 2001 From: Roland Geider Date: Sat, 25 Oct 2025 18:10:50 +0200 Subject: [PATCH] Move more usages to new exercise provider --- devtools_options.yaml | 3 +- ios/Podfile.lock | 6 + lib/database/powersync/database.dart | 4 +- lib/database/powersync/database.g.dart | 1004 ----------------- lib/database/powersync/tables/routines.dart | 3 +- lib/helpers/connectivity.dart | 42 + lib/main.dart | 93 +- lib/providers/exercise_data.dart | 3 +- lib/providers/exercise_data.g.dart | 4 +- lib/providers/exercise_state_notifier.dart | 123 +- lib/providers/exercise_state_notifier.g.dart | 4 +- lib/providers/exercises.dart | 44 - lib/providers/wger_base_riverpod.dart | 26 +- lib/screens/home_tabs_screen.dart | 5 +- lib/widgets/exercises/autocompleter.dart | 45 +- lib/widgets/exercises/filter_modal.dart | 7 +- lib/widgets/exercises/filter_row.dart | 1 + lib/widgets/routines/gym_mode/gym_mode.dart | 2 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 32 + pubspec.yaml | 1 + test/core/settings_test.mocks.dart | 56 - .../contribute_exercise_test.mocks.dart | 56 - .../exercises_detail_widget_test.mocks.dart | 56 - .../routine/routines_provider_test.mocks.dart | 56 - .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 27 files changed, 299 insertions(+), 1383 deletions(-) create mode 100644 lib/helpers/connectivity.dart diff --git a/devtools_options.yaml b/devtools_options.yaml index 75bd2b67..02a60610 100644 --- a/devtools_options.yaml +++ b/devtools_options.yaml @@ -1,3 +1,4 @@ extensions: - drift: true - - provider: true \ No newline at end of file + - provider: true + - shared_preferences: true \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 39f4f3a1..b5cbce09 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,6 +1,8 @@ PODS: - camera_avfoundation (0.0.1): - Flutter + - connectivity_plus (0.0.1): + - Flutter - Flutter (1.0.0) - flutter_keyboard_visibility (0.0.1): - Flutter @@ -60,6 +62,7 @@ PODS: DEPENDENCIES: - camera_avfoundation (from `.symlinks/plugins/camera_avfoundation/ios`) + - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - Flutter (from `Flutter`) - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - flutter_zxing (from `.symlinks/plugins/flutter_zxing/ios`) @@ -83,6 +86,8 @@ SPEC REPOS: EXTERNAL SOURCES: camera_avfoundation: :path: ".symlinks/plugins/camera_avfoundation/ios" + connectivity_plus: + :path: ".symlinks/plugins/connectivity_plus/ios" Flutter: :path: Flutter flutter_keyboard_visibility: @@ -114,6 +119,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: camera_avfoundation: be3be85408cd4126f250386828e9b1dfa40ab436 + connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619 flutter_zxing: e8bcc43bd3056c70c271b732ed94e7a16fd62f93 diff --git a/lib/database/powersync/database.dart b/lib/database/powersync/database.dart index 8a86b106..8accd309 100644 --- a/lib/database/powersync/database.dart +++ b/lib/database/powersync/database.dart @@ -12,13 +12,11 @@ import 'package:wger/models/exercises/muscle.dart'; import 'package:wger/models/exercises/translation.dart'; import 'package:wger/models/exercises/video.dart'; import 'package:wger/models/measurements/measurement_category.dart'; -import 'package:wger/models/workouts/log.dart'; import 'powersync.dart'; import 'tables/exercise.dart'; import 'tables/language.dart'; import 'tables/measurements.dart'; -import 'tables/routines.dart'; import 'tables/weight.dart'; part 'database.g.dart'; @@ -43,7 +41,7 @@ part 'database.g.dart'; // User data WeightEntryTable, MeasurementCategoryTable, - WorkoutLogTable, + // WorkoutLogTable, ], //include: {'queries.drift'}, ) diff --git a/lib/database/powersync/database.g.dart b/lib/database/powersync/database.g.dart index 8a229885..bbac68ea 100644 --- a/lib/database/powersync/database.g.dart +++ b/lib/database/powersync/database.g.dart @@ -3210,605 +3210,6 @@ class MeasurementCategoryTableCompanion extends UpdateCompanion { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - $WorkoutLogTableTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _idMeta = const VerificationMeta('id'); - @override - late final GeneratedColumn id = GeneratedColumn( - 'id', - aliasedName, - false, - type: DriftSqlType.string, - requiredDuringInsert: false, - clientDefault: () => uuid.v4(), - ); - static const VerificationMeta _exerciseIdMeta = const VerificationMeta( - 'exerciseId', - ); - @override - late final GeneratedColumn exerciseId = GeneratedColumn( - 'exercise_id', - aliasedName, - false, - type: DriftSqlType.int, - requiredDuringInsert: true, - ); - static const VerificationMeta _routineIdMeta = const VerificationMeta( - 'routineId', - ); - @override - late final GeneratedColumn routineId = GeneratedColumn( - 'routine_id', - aliasedName, - false, - type: DriftSqlType.int, - requiredDuringInsert: true, - ); - static const VerificationMeta _sessionIdMeta = const VerificationMeta( - 'sessionId', - ); - @override - late final GeneratedColumn sessionId = GeneratedColumn( - 'session_id', - aliasedName, - true, - type: DriftSqlType.int, - requiredDuringInsert: false, - ); - static const VerificationMeta _iterationMeta = const VerificationMeta( - 'iteration', - ); - @override - late final GeneratedColumn iteration = GeneratedColumn( - 'iteration', - aliasedName, - true, - type: DriftSqlType.int, - requiredDuringInsert: false, - ); - static const VerificationMeta _slotEntryIdMeta = const VerificationMeta( - 'slotEntryId', - ); - @override - late final GeneratedColumn slotEntryId = GeneratedColumn( - 'slot_entry_id', - aliasedName, - true, - type: DriftSqlType.int, - requiredDuringInsert: false, - ); - static const VerificationMeta _rirMeta = const VerificationMeta('rir'); - @override - late final GeneratedColumn rir = GeneratedColumn( - 'rir', - aliasedName, - true, - type: DriftSqlType.double, - requiredDuringInsert: false, - ); - static const VerificationMeta _rirTargetMeta = const VerificationMeta( - 'rirTarget', - ); - @override - late final GeneratedColumn rirTarget = GeneratedColumn( - 'rir_target', - aliasedName, - true, - type: DriftSqlType.double, - requiredDuringInsert: false, - ); - static const VerificationMeta _repetitionsMeta = const VerificationMeta( - 'repetitions', - ); - @override - late final GeneratedColumn repetitions = GeneratedColumn( - 'repetitions', - aliasedName, - false, - type: DriftSqlType.double, - requiredDuringInsert: true, - ); - static const VerificationMeta _repetitionsTargetMeta = const VerificationMeta( - 'repetitionsTarget', - ); - @override - late final GeneratedColumn repetitionsTarget = GeneratedColumn( - 'repetitions_target', - aliasedName, - false, - type: DriftSqlType.double, - requiredDuringInsert: true, - ); - static const VerificationMeta _repetitionsUnitIdMeta = const VerificationMeta( - 'repetitionsUnitId', - ); - @override - late final GeneratedColumn repetitionsUnitId = GeneratedColumn( - 'repetitions_unit_id', - aliasedName, - true, - type: DriftSqlType.int, - requiredDuringInsert: false, - ); - static const VerificationMeta _weightMeta = const VerificationMeta('weight'); - @override - late final GeneratedColumn weight = GeneratedColumn( - 'weight', - aliasedName, - false, - type: DriftSqlType.double, - requiredDuringInsert: true, - ); - static const VerificationMeta _weightTargetMeta = const VerificationMeta( - 'weightTarget', - ); - @override - late final GeneratedColumn weightTarget = GeneratedColumn( - 'weight_target', - aliasedName, - false, - type: DriftSqlType.double, - requiredDuringInsert: true, - ); - static const VerificationMeta _weightUnitIdMeta = const VerificationMeta( - 'weightUnitId', - ); - @override - late final GeneratedColumn weightUnitId = GeneratedColumn( - 'weight_unit_id', - aliasedName, - true, - type: DriftSqlType.int, - requiredDuringInsert: false, - ); - static const VerificationMeta _dateMeta = const VerificationMeta('date'); - @override - late final GeneratedColumn date = GeneratedColumn( - 'date', - aliasedName, - false, - type: DriftSqlType.dateTime, - requiredDuringInsert: true, - ); - @override - List get $columns => [ - id, - exerciseId, - routineId, - sessionId, - iteration, - slotEntryId, - rir, - rirTarget, - repetitions, - repetitionsTarget, - repetitionsUnitId, - weight, - weightTarget, - weightUnitId, - date, - ]; - @override - String get aliasedName => _alias ?? actualTableName; - @override - String get actualTableName => $name; - static const String $name = 'manager_workoutlog'; - @override - VerificationContext validateIntegrity( - Insertable instance, { - bool isInserting = false, - }) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('id')) { - context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta)); - } - if (data.containsKey('exercise_id')) { - context.handle( - _exerciseIdMeta, - exerciseId.isAcceptableOrUnknown(data['exercise_id']!, _exerciseIdMeta), - ); - } else if (isInserting) { - context.missing(_exerciseIdMeta); - } - if (data.containsKey('routine_id')) { - context.handle( - _routineIdMeta, - routineId.isAcceptableOrUnknown(data['routine_id']!, _routineIdMeta), - ); - } else if (isInserting) { - context.missing(_routineIdMeta); - } - if (data.containsKey('session_id')) { - context.handle( - _sessionIdMeta, - sessionId.isAcceptableOrUnknown(data['session_id']!, _sessionIdMeta), - ); - } - if (data.containsKey('iteration')) { - context.handle( - _iterationMeta, - iteration.isAcceptableOrUnknown(data['iteration']!, _iterationMeta), - ); - } - if (data.containsKey('slot_entry_id')) { - context.handle( - _slotEntryIdMeta, - slotEntryId.isAcceptableOrUnknown( - data['slot_entry_id']!, - _slotEntryIdMeta, - ), - ); - } - if (data.containsKey('rir')) { - context.handle( - _rirMeta, - rir.isAcceptableOrUnknown(data['rir']!, _rirMeta), - ); - } - if (data.containsKey('rir_target')) { - context.handle( - _rirTargetMeta, - rirTarget.isAcceptableOrUnknown(data['rir_target']!, _rirTargetMeta), - ); - } - if (data.containsKey('repetitions')) { - context.handle( - _repetitionsMeta, - repetitions.isAcceptableOrUnknown( - data['repetitions']!, - _repetitionsMeta, - ), - ); - } else if (isInserting) { - context.missing(_repetitionsMeta); - } - if (data.containsKey('repetitions_target')) { - context.handle( - _repetitionsTargetMeta, - repetitionsTarget.isAcceptableOrUnknown( - data['repetitions_target']!, - _repetitionsTargetMeta, - ), - ); - } else if (isInserting) { - context.missing(_repetitionsTargetMeta); - } - if (data.containsKey('repetitions_unit_id')) { - context.handle( - _repetitionsUnitIdMeta, - repetitionsUnitId.isAcceptableOrUnknown( - data['repetitions_unit_id']!, - _repetitionsUnitIdMeta, - ), - ); - } - if (data.containsKey('weight')) { - context.handle( - _weightMeta, - weight.isAcceptableOrUnknown(data['weight']!, _weightMeta), - ); - } else if (isInserting) { - context.missing(_weightMeta); - } - if (data.containsKey('weight_target')) { - context.handle( - _weightTargetMeta, - weightTarget.isAcceptableOrUnknown( - data['weight_target']!, - _weightTargetMeta, - ), - ); - } else if (isInserting) { - context.missing(_weightTargetMeta); - } - if (data.containsKey('weight_unit_id')) { - context.handle( - _weightUnitIdMeta, - weightUnitId.isAcceptableOrUnknown( - data['weight_unit_id']!, - _weightUnitIdMeta, - ), - ); - } - if (data.containsKey('date')) { - context.handle( - _dateMeta, - date.isAcceptableOrUnknown(data['date']!, _dateMeta), - ); - } else if (isInserting) { - context.missing(_dateMeta); - } - return context; - } - - @override - Set get $primaryKey => const {}; - @override - Log map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return Log( - id: attachedDatabase.typeMapping.read( - DriftSqlType.string, - data['${effectivePrefix}id'], - )!, - exerciseId: attachedDatabase.typeMapping.read( - DriftSqlType.int, - data['${effectivePrefix}exercise_id'], - )!, - iteration: attachedDatabase.typeMapping.read( - DriftSqlType.int, - data['${effectivePrefix}iteration'], - ), - slotEntryId: attachedDatabase.typeMapping.read( - DriftSqlType.int, - data['${effectivePrefix}slot_entry_id'], - ), - routineId: attachedDatabase.typeMapping.read( - DriftSqlType.int, - data['${effectivePrefix}routine_id'], - )!, - repetitions: attachedDatabase.typeMapping.read( - DriftSqlType.double, - data['${effectivePrefix}repetitions'], - )!, - repetitionsTarget: attachedDatabase.typeMapping.read( - DriftSqlType.double, - data['${effectivePrefix}repetitions_target'], - )!, - repetitionsUnitId: attachedDatabase.typeMapping.read( - DriftSqlType.int, - data['${effectivePrefix}repetitions_unit_id'], - ), - rir: attachedDatabase.typeMapping.read( - DriftSqlType.double, - data['${effectivePrefix}rir'], - ), - rirTarget: attachedDatabase.typeMapping.read( - DriftSqlType.double, - data['${effectivePrefix}rir_target'], - ), - weight: attachedDatabase.typeMapping.read( - DriftSqlType.double, - data['${effectivePrefix}weight'], - )!, - weightTarget: attachedDatabase.typeMapping.read( - DriftSqlType.double, - data['${effectivePrefix}weight_target'], - )!, - weightUnitId: attachedDatabase.typeMapping.read( - DriftSqlType.int, - data['${effectivePrefix}weight_unit_id'], - ), - date: attachedDatabase.typeMapping.read( - DriftSqlType.dateTime, - data['${effectivePrefix}date'], - )!, - ); - } - - @override - $WorkoutLogTableTable createAlias(String alias) { - return $WorkoutLogTableTable(attachedDatabase, alias); - } -} - -class WorkoutLogTableCompanion extends UpdateCompanion { - final Value id; - final Value exerciseId; - final Value routineId; - final Value sessionId; - final Value iteration; - final Value slotEntryId; - final Value rir; - final Value rirTarget; - final Value repetitions; - final Value repetitionsTarget; - final Value repetitionsUnitId; - final Value weight; - final Value weightTarget; - final Value weightUnitId; - final Value date; - final Value rowid; - const WorkoutLogTableCompanion({ - this.id = const Value.absent(), - this.exerciseId = const Value.absent(), - this.routineId = const Value.absent(), - this.sessionId = const Value.absent(), - this.iteration = const Value.absent(), - this.slotEntryId = const Value.absent(), - this.rir = const Value.absent(), - this.rirTarget = const Value.absent(), - this.repetitions = const Value.absent(), - this.repetitionsTarget = const Value.absent(), - this.repetitionsUnitId = const Value.absent(), - this.weight = const Value.absent(), - this.weightTarget = const Value.absent(), - this.weightUnitId = const Value.absent(), - this.date = const Value.absent(), - this.rowid = const Value.absent(), - }); - WorkoutLogTableCompanion.insert({ - this.id = const Value.absent(), - required int exerciseId, - required int routineId, - this.sessionId = const Value.absent(), - this.iteration = const Value.absent(), - this.slotEntryId = const Value.absent(), - this.rir = const Value.absent(), - this.rirTarget = const Value.absent(), - required double repetitions, - required double repetitionsTarget, - this.repetitionsUnitId = const Value.absent(), - required double weight, - required double weightTarget, - this.weightUnitId = const Value.absent(), - required DateTime date, - this.rowid = const Value.absent(), - }) : exerciseId = Value(exerciseId), - routineId = Value(routineId), - repetitions = Value(repetitions), - repetitionsTarget = Value(repetitionsTarget), - weight = Value(weight), - weightTarget = Value(weightTarget), - date = Value(date); - static Insertable custom({ - Expression? id, - Expression? exerciseId, - Expression? routineId, - Expression? sessionId, - Expression? iteration, - Expression? slotEntryId, - Expression? rir, - Expression? rirTarget, - Expression? repetitions, - Expression? repetitionsTarget, - Expression? repetitionsUnitId, - Expression? weight, - Expression? weightTarget, - Expression? weightUnitId, - Expression? date, - Expression? rowid, - }) { - return RawValuesInsertable({ - if (id != null) 'id': id, - if (exerciseId != null) 'exercise_id': exerciseId, - if (routineId != null) 'routine_id': routineId, - if (sessionId != null) 'session_id': sessionId, - if (iteration != null) 'iteration': iteration, - if (slotEntryId != null) 'slot_entry_id': slotEntryId, - if (rir != null) 'rir': rir, - if (rirTarget != null) 'rir_target': rirTarget, - if (repetitions != null) 'repetitions': repetitions, - if (repetitionsTarget != null) 'repetitions_target': repetitionsTarget, - if (repetitionsUnitId != null) 'repetitions_unit_id': repetitionsUnitId, - if (weight != null) 'weight': weight, - if (weightTarget != null) 'weight_target': weightTarget, - if (weightUnitId != null) 'weight_unit_id': weightUnitId, - if (date != null) 'date': date, - if (rowid != null) 'rowid': rowid, - }); - } - - WorkoutLogTableCompanion copyWith({ - Value? id, - Value? exerciseId, - Value? routineId, - Value? sessionId, - Value? iteration, - Value? slotEntryId, - Value? rir, - Value? rirTarget, - Value? repetitions, - Value? repetitionsTarget, - Value? repetitionsUnitId, - Value? weight, - Value? weightTarget, - Value? weightUnitId, - Value? date, - Value? rowid, - }) { - return WorkoutLogTableCompanion( - id: id ?? this.id, - exerciseId: exerciseId ?? this.exerciseId, - routineId: routineId ?? this.routineId, - sessionId: sessionId ?? this.sessionId, - iteration: iteration ?? this.iteration, - slotEntryId: slotEntryId ?? this.slotEntryId, - rir: rir ?? this.rir, - rirTarget: rirTarget ?? this.rirTarget, - repetitions: repetitions ?? this.repetitions, - repetitionsTarget: repetitionsTarget ?? this.repetitionsTarget, - repetitionsUnitId: repetitionsUnitId ?? this.repetitionsUnitId, - weight: weight ?? this.weight, - weightTarget: weightTarget ?? this.weightTarget, - weightUnitId: weightUnitId ?? this.weightUnitId, - date: date ?? this.date, - rowid: rowid ?? this.rowid, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (id.present) { - map['id'] = Variable(id.value); - } - if (exerciseId.present) { - map['exercise_id'] = Variable(exerciseId.value); - } - if (routineId.present) { - map['routine_id'] = Variable(routineId.value); - } - if (sessionId.present) { - map['session_id'] = Variable(sessionId.value); - } - if (iteration.present) { - map['iteration'] = Variable(iteration.value); - } - if (slotEntryId.present) { - map['slot_entry_id'] = Variable(slotEntryId.value); - } - if (rir.present) { - map['rir'] = Variable(rir.value); - } - if (rirTarget.present) { - map['rir_target'] = Variable(rirTarget.value); - } - if (repetitions.present) { - map['repetitions'] = Variable(repetitions.value); - } - if (repetitionsTarget.present) { - map['repetitions_target'] = Variable(repetitionsTarget.value); - } - if (repetitionsUnitId.present) { - map['repetitions_unit_id'] = Variable(repetitionsUnitId.value); - } - if (weight.present) { - map['weight'] = Variable(weight.value); - } - if (weightTarget.present) { - map['weight_target'] = Variable(weightTarget.value); - } - if (weightUnitId.present) { - map['weight_unit_id'] = Variable(weightUnitId.value); - } - if (date.present) { - map['date'] = Variable(date.value); - } - if (rowid.present) { - map['rowid'] = Variable(rowid.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('WorkoutLogTableCompanion(') - ..write('id: $id, ') - ..write('exerciseId: $exerciseId, ') - ..write('routineId: $routineId, ') - ..write('sessionId: $sessionId, ') - ..write('iteration: $iteration, ') - ..write('slotEntryId: $slotEntryId, ') - ..write('rir: $rir, ') - ..write('rirTarget: $rirTarget, ') - ..write('repetitions: $repetitions, ') - ..write('repetitionsTarget: $repetitionsTarget, ') - ..write('repetitionsUnitId: $repetitionsUnitId, ') - ..write('weight: $weight, ') - ..write('weightTarget: $weightTarget, ') - ..write('weightUnitId: $weightUnitId, ') - ..write('date: $date, ') - ..write('rowid: $rowid') - ..write(')')) - .toString(); - } -} - abstract class _$DriftPowersyncDatabase extends GeneratedDatabase { _$DriftPowersyncDatabase(QueryExecutor e) : super(e); $DriftPowersyncDatabaseManager get managers => $DriftPowersyncDatabaseManager(this); @@ -3830,9 +3231,6 @@ abstract class _$DriftPowersyncDatabase extends GeneratedDatabase { ); late final $MeasurementCategoryTableTable measurementCategoryTable = $MeasurementCategoryTableTable(this); - late final $WorkoutLogTableTable workoutLogTable = $WorkoutLogTableTable( - this, - ); @override Iterable> get allTables => allSchemaEntities.whereType>(); @@ -3851,7 +3249,6 @@ abstract class _$DriftPowersyncDatabase extends GeneratedDatabase { exerciseVideoTable, weightEntryTable, measurementCategoryTable, - workoutLogTable, ]; @override DriftDatabaseOptions get options => const DriftDatabaseOptions(storeDateTimeAsText: true); @@ -6355,405 +5752,6 @@ typedef $$MeasurementCategoryTableTableProcessedTableManager = MeasurementCategory, PrefetchHooks Function() >; -typedef $$WorkoutLogTableTableCreateCompanionBuilder = - WorkoutLogTableCompanion Function({ - Value id, - required int exerciseId, - required int routineId, - Value sessionId, - Value iteration, - Value slotEntryId, - Value rir, - Value rirTarget, - required double repetitions, - required double repetitionsTarget, - Value repetitionsUnitId, - required double weight, - required double weightTarget, - Value weightUnitId, - required DateTime date, - Value rowid, - }); -typedef $$WorkoutLogTableTableUpdateCompanionBuilder = - WorkoutLogTableCompanion Function({ - Value id, - Value exerciseId, - Value routineId, - Value sessionId, - Value iteration, - Value slotEntryId, - Value rir, - Value rirTarget, - Value repetitions, - Value repetitionsTarget, - Value repetitionsUnitId, - Value weight, - Value weightTarget, - Value weightUnitId, - Value date, - Value rowid, - }); - -class $$WorkoutLogTableTableFilterComposer - extends Composer<_$DriftPowersyncDatabase, $WorkoutLogTableTable> { - $$WorkoutLogTableTableFilterComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - ColumnFilters get id => $composableBuilder( - column: $table.id, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get exerciseId => $composableBuilder( - column: $table.exerciseId, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get routineId => $composableBuilder( - column: $table.routineId, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get sessionId => $composableBuilder( - column: $table.sessionId, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get iteration => $composableBuilder( - column: $table.iteration, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get slotEntryId => $composableBuilder( - column: $table.slotEntryId, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get rir => $composableBuilder( - column: $table.rir, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get rirTarget => $composableBuilder( - column: $table.rirTarget, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get repetitions => $composableBuilder( - column: $table.repetitions, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get repetitionsTarget => $composableBuilder( - column: $table.repetitionsTarget, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get repetitionsUnitId => $composableBuilder( - column: $table.repetitionsUnitId, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get weight => $composableBuilder( - column: $table.weight, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get weightTarget => $composableBuilder( - column: $table.weightTarget, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get weightUnitId => $composableBuilder( - column: $table.weightUnitId, - builder: (column) => ColumnFilters(column), - ); - - ColumnFilters get date => $composableBuilder( - column: $table.date, - builder: (column) => ColumnFilters(column), - ); -} - -class $$WorkoutLogTableTableOrderingComposer - extends Composer<_$DriftPowersyncDatabase, $WorkoutLogTableTable> { - $$WorkoutLogTableTableOrderingComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - ColumnOrderings get id => $composableBuilder( - column: $table.id, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get exerciseId => $composableBuilder( - column: $table.exerciseId, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get routineId => $composableBuilder( - column: $table.routineId, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get sessionId => $composableBuilder( - column: $table.sessionId, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get iteration => $composableBuilder( - column: $table.iteration, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get slotEntryId => $composableBuilder( - column: $table.slotEntryId, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get rir => $composableBuilder( - column: $table.rir, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get rirTarget => $composableBuilder( - column: $table.rirTarget, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get repetitions => $composableBuilder( - column: $table.repetitions, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get repetitionsTarget => $composableBuilder( - column: $table.repetitionsTarget, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get repetitionsUnitId => $composableBuilder( - column: $table.repetitionsUnitId, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get weight => $composableBuilder( - column: $table.weight, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get weightTarget => $composableBuilder( - column: $table.weightTarget, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get weightUnitId => $composableBuilder( - column: $table.weightUnitId, - builder: (column) => ColumnOrderings(column), - ); - - ColumnOrderings get date => $composableBuilder( - column: $table.date, - builder: (column) => ColumnOrderings(column), - ); -} - -class $$WorkoutLogTableTableAnnotationComposer - extends Composer<_$DriftPowersyncDatabase, $WorkoutLogTableTable> { - $$WorkoutLogTableTableAnnotationComposer({ - required super.$db, - required super.$table, - super.joinBuilder, - super.$addJoinBuilderToRootComposer, - super.$removeJoinBuilderFromRootComposer, - }); - GeneratedColumn get id => - $composableBuilder(column: $table.id, builder: (column) => column); - - GeneratedColumn get exerciseId => $composableBuilder( - column: $table.exerciseId, - builder: (column) => column, - ); - - GeneratedColumn get routineId => - $composableBuilder(column: $table.routineId, builder: (column) => column); - - GeneratedColumn get sessionId => - $composableBuilder(column: $table.sessionId, builder: (column) => column); - - GeneratedColumn get iteration => - $composableBuilder(column: $table.iteration, builder: (column) => column); - - GeneratedColumn get slotEntryId => $composableBuilder( - column: $table.slotEntryId, - builder: (column) => column, - ); - - GeneratedColumn get rir => - $composableBuilder(column: $table.rir, builder: (column) => column); - - GeneratedColumn get rirTarget => - $composableBuilder(column: $table.rirTarget, builder: (column) => column); - - GeneratedColumn get repetitions => $composableBuilder( - column: $table.repetitions, - builder: (column) => column, - ); - - GeneratedColumn get repetitionsTarget => $composableBuilder( - column: $table.repetitionsTarget, - builder: (column) => column, - ); - - GeneratedColumn get repetitionsUnitId => $composableBuilder( - column: $table.repetitionsUnitId, - builder: (column) => column, - ); - - GeneratedColumn get weight => - $composableBuilder(column: $table.weight, builder: (column) => column); - - GeneratedColumn get weightTarget => $composableBuilder( - column: $table.weightTarget, - builder: (column) => column, - ); - - GeneratedColumn get weightUnitId => $composableBuilder( - column: $table.weightUnitId, - builder: (column) => column, - ); - - GeneratedColumn get date => - $composableBuilder(column: $table.date, builder: (column) => column); -} - -class $$WorkoutLogTableTableTableManager - extends - RootTableManager< - _$DriftPowersyncDatabase, - $WorkoutLogTableTable, - Log, - $$WorkoutLogTableTableFilterComposer, - $$WorkoutLogTableTableOrderingComposer, - $$WorkoutLogTableTableAnnotationComposer, - $$WorkoutLogTableTableCreateCompanionBuilder, - $$WorkoutLogTableTableUpdateCompanionBuilder, - (Log, BaseReferences<_$DriftPowersyncDatabase, $WorkoutLogTableTable, Log>), - Log, - PrefetchHooks Function() - > { - $$WorkoutLogTableTableTableManager( - _$DriftPowersyncDatabase db, - $WorkoutLogTableTable table, - ) : super( - TableManagerState( - db: db, - table: table, - createFilteringComposer: () => - $$WorkoutLogTableTableFilterComposer($db: db, $table: table), - createOrderingComposer: () => - $$WorkoutLogTableTableOrderingComposer($db: db, $table: table), - createComputedFieldComposer: () => - $$WorkoutLogTableTableAnnotationComposer($db: db, $table: table), - updateCompanionCallback: - ({ - Value id = const Value.absent(), - Value exerciseId = const Value.absent(), - Value routineId = const Value.absent(), - Value sessionId = const Value.absent(), - Value iteration = const Value.absent(), - Value slotEntryId = const Value.absent(), - Value rir = const Value.absent(), - Value rirTarget = const Value.absent(), - Value repetitions = const Value.absent(), - Value repetitionsTarget = const Value.absent(), - Value repetitionsUnitId = const Value.absent(), - Value weight = const Value.absent(), - Value weightTarget = const Value.absent(), - Value weightUnitId = const Value.absent(), - Value date = const Value.absent(), - Value rowid = const Value.absent(), - }) => WorkoutLogTableCompanion( - id: id, - exerciseId: exerciseId, - routineId: routineId, - sessionId: sessionId, - iteration: iteration, - slotEntryId: slotEntryId, - rir: rir, - rirTarget: rirTarget, - repetitions: repetitions, - repetitionsTarget: repetitionsTarget, - repetitionsUnitId: repetitionsUnitId, - weight: weight, - weightTarget: weightTarget, - weightUnitId: weightUnitId, - date: date, - rowid: rowid, - ), - createCompanionCallback: - ({ - Value id = const Value.absent(), - required int exerciseId, - required int routineId, - Value sessionId = const Value.absent(), - Value iteration = const Value.absent(), - Value slotEntryId = const Value.absent(), - Value rir = const Value.absent(), - Value rirTarget = const Value.absent(), - required double repetitions, - required double repetitionsTarget, - Value repetitionsUnitId = const Value.absent(), - required double weight, - required double weightTarget, - Value weightUnitId = const Value.absent(), - required DateTime date, - Value rowid = const Value.absent(), - }) => WorkoutLogTableCompanion.insert( - id: id, - exerciseId: exerciseId, - routineId: routineId, - sessionId: sessionId, - iteration: iteration, - slotEntryId: slotEntryId, - rir: rir, - rirTarget: rirTarget, - repetitions: repetitions, - repetitionsTarget: repetitionsTarget, - repetitionsUnitId: repetitionsUnitId, - weight: weight, - weightTarget: weightTarget, - weightUnitId: weightUnitId, - date: date, - rowid: rowid, - ), - withReferenceMapper: (p0) => - p0.map((e) => (e.readTable(table), BaseReferences(db, table, e))).toList(), - prefetchHooksCallback: null, - ), - ); -} - -typedef $$WorkoutLogTableTableProcessedTableManager = - ProcessedTableManager< - _$DriftPowersyncDatabase, - $WorkoutLogTableTable, - Log, - $$WorkoutLogTableTableFilterComposer, - $$WorkoutLogTableTableOrderingComposer, - $$WorkoutLogTableTableAnnotationComposer, - $$WorkoutLogTableTableCreateCompanionBuilder, - $$WorkoutLogTableTableUpdateCompanionBuilder, - (Log, BaseReferences<_$DriftPowersyncDatabase, $WorkoutLogTableTable, Log>), - Log, - PrefetchHooks Function() - >; class $DriftPowersyncDatabaseManager { final _$DriftPowersyncDatabase _db; @@ -6793,6 +5791,4 @@ class $DriftPowersyncDatabaseManager { _db, _db.measurementCategoryTable, ); - $$WorkoutLogTableTableTableManager get workoutLogTable => - $$WorkoutLogTableTableTableManager(_db, _db.workoutLogTable); } diff --git a/lib/database/powersync/tables/routines.dart b/lib/database/powersync/tables/routines.dart index 8cfff277..21b2aae7 100644 --- a/lib/database/powersync/tables/routines.dart +++ b/lib/database/powersync/tables/routines.dart @@ -1,8 +1,7 @@ import 'package:drift/drift.dart'; import 'package:powersync/powersync.dart' show uuid; -import 'package:wger/models/workouts/log.dart'; -@UseRowClass(Log) +// @UseRowClass(Log) class WorkoutLogTable extends Table { @override String get tableName => 'manager_workoutlog'; diff --git a/lib/helpers/connectivity.dart b/lib/helpers/connectivity.dart new file mode 100644 index 00000000..9d833747 --- /dev/null +++ b/lib/helpers/connectivity.dart @@ -0,0 +1,42 @@ +/* + * This file is part of wger Workout Manager . + * Copyright (c) 2020, 2025 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import 'package:connectivity_plus/connectivity_plus.dart'; + +Future hasNetworkConnection({Duration timeout = const Duration(seconds: 1)}) async { + final connectivityResult = await Connectivity().checkConnectivity(); + + final allowed = [ + ConnectivityResult.mobile, + ConnectivityResult.wifi, + ConnectivityResult.ethernet, + ]; + + if (!connectivityResult.any((c) => allowed.contains(c))) { + return false; + } + + return true; + + // try { + // final result = await InternetAddress.lookup('example.com').timeout(timeout); + // return result.isNotEmpty && result[0].rawAddress.isNotEmpty; + // } catch (_) { + // return false; + // } +} diff --git a/lib/main.dart b/lib/main.dart index 73b7278e..59e1d721 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -34,6 +34,7 @@ import 'package:wger/providers/measurement.dart'; import 'package:wger/providers/nutrition.dart'; import 'package:wger/providers/routines.dart'; import 'package:wger/providers/user.dart'; +import 'package:wger/providers/wger_base_riverpod.dart'; import 'package:wger/screens/add_exercise_screen.dart'; import 'package:wger/screens/auth_screen.dart'; import 'package:wger/screens/configure_plates_screen.dart'; @@ -128,7 +129,7 @@ void main() async { }; // Application - runApp(const riverpod.ProviderScope(child: MainApp())); + runApp(const MainApp()); } class MainApp extends StatelessWidget { @@ -209,46 +210,56 @@ class MainApp extends StatelessWidget { ), ], child: Consumer( - builder: (ctx, auth, _) => Consumer( - builder: (ctx, user, _) => MaterialApp( - title: 'wger', - navigatorKey: navigatorKey, - theme: wgerLightTheme, - darkTheme: wgerDarkTheme, - highContrastTheme: wgerLightThemeHc, - highContrastDarkTheme: wgerDarkThemeHc, - themeMode: user.themeMode, - home: _getHomeScreen(auth), - routes: { - DashboardScreen.routeName: (ctx) => const DashboardScreen(), - FormScreen.routeName: (ctx) => const FormScreen(), - GalleryScreen.routeName: (ctx) => const GalleryScreen(), - GymModeScreen.routeName: (ctx) => const GymModeScreen(), - HomeTabsScreen.routeName: (ctx) => HomeTabsScreen(), - MeasurementCategoriesScreen.routeName: (ctx) => const MeasurementCategoriesScreen(), - MeasurementEntriesScreen.routeName: (ctx) => const MeasurementEntriesScreen(), - NutritionalPlansScreen.routeName: (ctx) => const NutritionalPlansScreen(), - NutritionalDiaryScreen.routeName: (ctx) => const NutritionalDiaryScreen(), - NutritionalPlanScreen.routeName: (ctx) => const NutritionalPlanScreen(), - LogMealsScreen.routeName: (ctx) => const LogMealsScreen(), - LogMealScreen.routeName: (ctx) => const LogMealScreen(), - WeightScreen.routeName: (ctx) => const WeightScreen(), - RoutineScreen.routeName: (ctx) => const RoutineScreen(), - RoutineEditScreen.routeName: (ctx) => const RoutineEditScreen(), - WorkoutLogsScreen.routeName: (ctx) => const WorkoutLogsScreen(), - RoutineListScreen.routeName: (ctx) => const RoutineListScreen(), - ExercisesScreen.routeName: (ctx) => const ExercisesScreen(), - ExerciseDetailScreen.routeName: (ctx) => const ExerciseDetailScreen(), - AddExerciseScreen.routeName: (ctx) => const AddExerciseScreen(), - AboutPage.routeName: (ctx) => const AboutPage(), - SettingsPage.routeName: (ctx) => const SettingsPage(), - LogOverviewPage.routeName: (ctx) => const LogOverviewPage(), - ConfigurePlatesScreen.routeName: (ctx) => const ConfigurePlatesScreen(), - }, - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - ), - ), + builder: (ctx, auth, _) { + final baseInstance = WgerBaseProvider(Provider.of(ctx, listen: false)); + + return Consumer( + builder: (ctx, user, _) => riverpod.ProviderScope( + overrides: [ + wgerBaseProvider.overrideWithValue(baseInstance), + ], + child: MaterialApp( + title: 'wger', + navigatorKey: navigatorKey, + theme: wgerLightTheme, + darkTheme: wgerDarkTheme, + highContrastTheme: wgerLightThemeHc, + highContrastDarkTheme: wgerDarkThemeHc, + themeMode: user.themeMode, + home: _getHomeScreen(auth), + routes: { + DashboardScreen.routeName: (ctx) => const DashboardScreen(), + FormScreen.routeName: (ctx) => const FormScreen(), + GalleryScreen.routeName: (ctx) => const GalleryScreen(), + GymModeScreen.routeName: (ctx) => const GymModeScreen(), + HomeTabsScreen.routeName: (ctx) => HomeTabsScreen(), + MeasurementCategoriesScreen.routeName: (ctx) => + const MeasurementCategoriesScreen(), + MeasurementEntriesScreen.routeName: (ctx) => const MeasurementEntriesScreen(), + NutritionalPlansScreen.routeName: (ctx) => const NutritionalPlansScreen(), + NutritionalDiaryScreen.routeName: (ctx) => const NutritionalDiaryScreen(), + NutritionalPlanScreen.routeName: (ctx) => const NutritionalPlanScreen(), + LogMealsScreen.routeName: (ctx) => const LogMealsScreen(), + LogMealScreen.routeName: (ctx) => const LogMealScreen(), + WeightScreen.routeName: (ctx) => const WeightScreen(), + RoutineScreen.routeName: (ctx) => const RoutineScreen(), + RoutineEditScreen.routeName: (ctx) => const RoutineEditScreen(), + WorkoutLogsScreen.routeName: (ctx) => const WorkoutLogsScreen(), + RoutineListScreen.routeName: (ctx) => const RoutineListScreen(), + ExercisesScreen.routeName: (ctx) => const ExercisesScreen(), + ExerciseDetailScreen.routeName: (ctx) => const ExerciseDetailScreen(), + AddExerciseScreen.routeName: (ctx) => const AddExerciseScreen(), + AboutPage.routeName: (ctx) => const AboutPage(), + SettingsPage.routeName: (ctx) => const SettingsPage(), + LogOverviewPage.routeName: (ctx) => const LogOverviewPage(), + ConfigurePlatesScreen.routeName: (ctx) => const ConfigurePlatesScreen(), + }, + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + ), + ), + ); + }, ), ); } diff --git a/lib/providers/exercise_data.dart b/lib/providers/exercise_data.dart index a0a3c70c..b2a3a1ce 100644 --- a/lib/providers/exercise_data.dart +++ b/lib/providers/exercise_data.dart @@ -27,12 +27,13 @@ import 'package:wger/models/exercises/muscle.dart'; part 'exercise_data.g.dart'; -@riverpod +@Riverpod(keepAlive: true) final class ExerciseNotifier extends _$ExerciseNotifier { final _logger = Logger('ExerciseNotifier'); @override Stream> build() { + ref.keepAlive(); final db = ref.read(driftPowerSyncDatabase); _logger.fine('Building exercise stream'); diff --git a/lib/providers/exercise_data.g.dart b/lib/providers/exercise_data.g.dart index 5b16c856..bf4aeb7d 100644 --- a/lib/providers/exercise_data.g.dart +++ b/lib/providers/exercise_data.g.dart @@ -20,7 +20,7 @@ final class ExerciseNotifierProvider argument: null, retry: null, name: r'exerciseProvider', - isAutoDispose: true, + isAutoDispose: false, dependencies: null, $allTransitiveDependencies: null, ); @@ -33,7 +33,7 @@ final class ExerciseNotifierProvider ExerciseNotifier create() => ExerciseNotifier(); } -String _$exerciseNotifierHash() => r'b8db6a2b5e05f4ba3f7a7677999816298209f5db'; +String _$exerciseNotifierHash() => r'897551df3c53c72427a050c9559647aa9f8b59dd'; abstract class _$ExerciseNotifier extends $StreamNotifier> { Stream> build(); diff --git a/lib/providers/exercise_state_notifier.dart b/lib/providers/exercise_state_notifier.dart index 9ebd452a..1009caf5 100644 --- a/lib/providers/exercise_state_notifier.dart +++ b/lib/providers/exercise_state_notifier.dart @@ -16,22 +16,29 @@ * along with this program. If not, see . */ +import 'dart:async'; + import 'package:logging/logging.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:wger/helpers/consts.dart'; import 'package:wger/models/exercises/category.dart'; import 'package:wger/models/exercises/equipment.dart'; import 'package:wger/models/exercises/exercise.dart'; import 'package:wger/providers/exercise_data.dart'; import 'package:wger/providers/exercise_state.dart'; +import 'package:wger/providers/wger_base_riverpod.dart'; part 'exercise_state_notifier.g.dart'; -@riverpod +@Riverpod(keepAlive: true) final class ExerciseStateNotifier extends _$ExerciseStateNotifier { final _logger = Logger('ExerciseStateNotifier'); + static const exerciseInfoUrlPath = 'exerciseinfo'; + @override ExerciseState build() { + _logger.finer('Building ExerciseStateNotifier'); state = ExerciseState(isLoading: true); // Load exercises @@ -104,16 +111,20 @@ final class ExerciseStateNotifier extends _$ExerciseStateNotifier { } if (updated) { - setFilters(filters); + setFilters(filters, LANGUAGE_SHORT_ENGLISH); } } - void setFilters(Filters filters) { - final filtered = _applyFilters(state.exercises, filters); + void setFilters(Filters filters, [String languageCode = LANGUAGE_SHORT_ENGLISH]) { + final filtered = _applyFilters(state.exercises, filters, languageCode: languageCode); state = state.copyWith(filters: filters, filteredExercises: filtered); } - List _applyFilters(List all, Filters filters) { + List _applyFilters( + List all, + Filters filters, { + String languageCode = LANGUAGE_SHORT_ENGLISH, + }) { if (filters.isNothingMarked && (filters.searchTerm.length <= 1)) { return all; } @@ -123,8 +134,7 @@ final class ExerciseStateNotifier extends _$ExerciseStateNotifier { final term = filters.searchTerm.toLowerCase(); items = items.where((e) { // TODO: FullTextSearch? - // TODO!!!! translations - final title = (e.getTranslation('en').name ?? '').toLowerCase(); + final title = (e.getTranslation(languageCode).name ?? '').toLowerCase(); return title.contains(term); }).toList(); } @@ -150,40 +160,89 @@ final class ExerciseStateNotifier extends _$ExerciseStateNotifier { Future> searchExercise( String term, { - bool useServer = false, + bool useOnlineSearch = true, String languageCode = 'en', bool searchEnglish = false, }) async { - if (term.trim().length <= 1) { + if (term.isEmpty) { return []; } - // Local mode: search in the sqlite db - if (!useServer) { - final languages = [languageCode]; - if (searchEnglish && languageCode != 'en') { - languages.add('en'); - } + final searchMethod = useOnlineSearch ? searchExerciseOnline : searchExerciseLocal; + return searchMethod( + term, + languageCode: languageCode, + searchEnglish: searchEnglish, + ); + } - final List out = []; + Future> searchExerciseOnline( + String term, { + String languageCode = 'en', + bool searchEnglish = false, + }) async { + final wgerBase = ref.read(wgerBaseProvider); + _logger.info('Online search for exercises: $term'); - for (final e in state.exercises) { - var matched = false; - for (final lang in languages) { - final title = (e.getTranslation(lang).name ?? '').toLowerCase(); - if (title.contains(term.toLowerCase())) { - matched = true; - break; - } - } - if (matched) { - out.add(e); - } - } - return out; + if (term.length <= 1) { + return []; } - // Online mode, use server-side search API - return []; + final languages = [languageCode]; + if (searchEnglish && languageCode != LANGUAGE_SHORT_ENGLISH) { + languages.add(LANGUAGE_SHORT_ENGLISH); + } + + // Send the request + final result = await wgerBase.fetch( + wgerBase.makeUrl( + exerciseInfoUrlPath, + query: { + 'name__search': term, + 'language__code': languages.join(','), + 'limit': API_RESULTS_PAGE_SIZE, + }, + ), + ); + + // Load the exercises + final ids = (result['results'] as List).map((data) => data['id'] as int).toList(); + + // TODO: fix this! Why is the ref of stateProvider always disposed? + return state.exercises.where((e) => ids.contains(e.id)).toList(); + + return (result['results'] as List) + .map((data) => Exercise.fromApiDataJson(data as Map, [])) + .toList(); + } + + Future> searchExerciseLocal( + String term, { + String languageCode = 'en', + bool searchEnglish = false, + }) async { + _logger.fine('Local search for exercises: $term'); + + final languages = [languageCode]; + if (searchEnglish && languageCode != 'en') { + languages.add('en'); + } + + final List out = []; + + for (final e in state.exercises) { + var matched = false; + for (final lang in languages) { + final title = (e.getTranslation(lang).name ?? '').toLowerCase(); + if (title.contains(term.toLowerCase())) { + matched = true; + break; + } + } + if (matched) { + out.add(e); + } + } + return out; } } diff --git a/lib/providers/exercise_state_notifier.g.dart b/lib/providers/exercise_state_notifier.g.dart index 6d19309c..ef7b2391 100644 --- a/lib/providers/exercise_state_notifier.g.dart +++ b/lib/providers/exercise_state_notifier.g.dart @@ -20,7 +20,7 @@ final class ExerciseStateNotifierProvider argument: null, retry: null, name: r'exerciseStateProvider', - isAutoDispose: true, + isAutoDispose: false, dependencies: null, $allTransitiveDependencies: null, ); @@ -41,7 +41,7 @@ final class ExerciseStateNotifierProvider } } -String _$exerciseStateNotifierHash() => r'c3070d53059705b03595597f099ded2b7efb5a93'; +String _$exerciseStateNotifierHash() => r'0190aca10f979de44254c429212e8a9e614cb167'; abstract class _$ExerciseStateNotifier extends $Notifier { ExerciseState build(); diff --git a/lib/providers/exercises.dart b/lib/providers/exercises.dart index 6c9cb6aa..e2b335e6 100644 --- a/lib/providers/exercises.dart +++ b/lib/providers/exercises.dart @@ -49,7 +49,6 @@ class ExercisesProvider with ChangeNotifier { static const exerciseUrlPath = 'exercise'; static const exerciseInfoUrlPath = 'exerciseinfo'; - static const exerciseSearchPath = 'exercise/search'; static const categoriesUrlPath = 'exercisecategory'; static const musclesUrlPath = 'muscle'; @@ -557,47 +556,4 @@ class ExercisesProvider with ChangeNotifier { await prefs.setString(PREFS_LAST_UPDATED_EQUIPMENT, validTill.toIso8601String()); _logger.fine('Saved ${_equipment.length} equipment entries to cache (valid till $validTill)'); } - - /// Searches for an exercise - /// - /// We could do this locally, but the server has better text searching capabilities - /// with postgresql. - Future> searchExercise( - String name, { - String languageCode = LANGUAGE_SHORT_ENGLISH, - bool searchEnglish = false, - }) async { - if (name.length <= 1) { - return []; - } - - final languages = [languageCode]; - if (searchEnglish && languageCode != LANGUAGE_SHORT_ENGLISH) { - languages.add(LANGUAGE_SHORT_ENGLISH); - } - - // Send the request - final result = await baseProvider.fetch( - baseProvider.makeUrl( - exerciseSearchPath, - query: {'term': name, 'language': languages.join(',')}, - ), - ); - - // Load the exercises - final results = ExerciseApiSearch.fromJson(result); - - final List out = []; - for (final result in results.suggestions) { - final exercise = await fetchAndSetExercise(result.data.exerciseId); - if (exercise != null) { - out.add(exercise); - } - } - // return Future.wait( - // results.suggestions.map((e) => fetchAndSetExercise(e.data.exerciseId)), - // ); - - return out; - } } diff --git a/lib/providers/wger_base_riverpod.dart b/lib/providers/wger_base_riverpod.dart index f69f925d..b2a01d1f 100644 --- a/lib/providers/wger_base_riverpod.dart +++ b/lib/providers/wger_base_riverpod.dart @@ -1,4 +1,20 @@ -// filepath: /Users/roland/Entwicklung/wger/flutter/lib/providers/wger_base_riverpod.dart +/* + * This file is part of wger Workout Manager . + * Copyright (C) 2020, 2025 wger Team + * + * wger Workout Manager is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:wger/providers/auth.dart'; @@ -8,6 +24,8 @@ import 'package:wger/providers/base_provider.dart'; /// to a [WgerBaseProvider] used by repositories. /// /// Usage: ref.watch(wgerBaseProvider(authProvider)) -final wgerBaseProvider = Provider.family( - (ref, auth) => WgerBaseProvider(auth), -); +final wgerBaseProvider = Provider((ref) { + throw UnimplementedError( + 'Override wgerBaseProvider in a ProviderScope with your existing WgerBaseProvider instance', + ); +}); diff --git a/lib/screens/home_tabs_screen.dart b/lib/screens/home_tabs_screen.dart index feae4a4a..beb6796f 100644 --- a/lib/screens/home_tabs_screen.dart +++ b/lib/screens/home_tabs_screen.dart @@ -25,6 +25,8 @@ import 'package:rive/rive.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/powersync/connector.dart'; import 'package:wger/providers/auth.dart'; +import 'package:wger/providers/body_weight.dart'; +import 'package:wger/providers/exercise_state_notifier.dart'; import 'package:wger/providers/exercises.dart'; import 'package:wger/providers/gallery.dart'; import 'package:wger/providers/measurement.dart'; @@ -120,7 +122,8 @@ class _HomeTabsScreenState extends riverpod.ConsumerState nutritionPlansProvider.fetchIngredientsFromCache(), exercisesProvider.fetchAndSetInitialData(), ]); - exercisesProvider.fetchAndSetAllExercises(); + ref.read(exerciseStateProvider); + ref.read(weightEntryProvider()); // Workaround for https://github.com/wger-project/flutter/issues/901 // It seems that it can happen that sometimes the units were not loaded properly diff --git a/lib/widgets/exercises/autocompleter.dart b/lib/widgets/exercises/autocompleter.dart index e333045a..aa0a7358 100644 --- a/lib/widgets/exercises/autocompleter.dart +++ b/lib/widgets/exercises/autocompleter.dart @@ -1,30 +1,33 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; -import 'package:provider/provider.dart'; +import 'package:wger/helpers/connectivity.dart'; import 'package:wger/helpers/consts.dart'; import 'package:wger/l10n/generated/app_localizations.dart'; import 'package:wger/models/exercises/exercise.dart'; -import 'package:wger/providers/exercises.dart'; +import 'package:wger/providers/exercise_state_notifier.dart'; import 'package:wger/screens/add_exercise_screen.dart'; import 'package:wger/widgets/exercises/images.dart'; typedef ExerciseSelectedCallback = void Function(Exercise exercise); -class ExerciseAutocompleter extends StatefulWidget { +class ExerciseAutocompleter extends ConsumerStatefulWidget { final ExerciseSelectedCallback onExerciseSelected; const ExerciseAutocompleter({required this.onExerciseSelected}); @override - State createState() => _ExerciseAutocompleterState(); + ConsumerState createState() => _ExerciseAutocompleterState(); } -class _ExerciseAutocompleterState extends State { +class _ExerciseAutocompleterState extends ConsumerState { bool _searchEnglish = true; final _exercisesController = TextEditingController(); @override Widget build(BuildContext context) { + final languageCode = Localizations.localeOf(context).languageCode; + return Column( // mainAxisSize: MainAxisSize.min, children: [ @@ -80,35 +83,37 @@ class _ExerciseAutocompleterState extends State { ), ); }, - suggestionsCallback: (pattern) { - if (pattern == '') { + suggestionsCallback: (pattern) async { + if (pattern.isEmpty) { return null; } - return context.read().searchExercise( - pattern, - languageCode: Localizations.localeOf(context).languageCode, - searchEnglish: _searchEnglish, - ); + + return ref + .read(exerciseStateProvider.notifier) + .searchExercise( + pattern, + languageCode: languageCode, + searchEnglish: _searchEnglish, + useOnlineSearch: await hasNetworkConnection(), + ); }, itemBuilder: ( BuildContext context, - Exercise exerciseSuggestion, + Exercise exercise, ) => ListTile( - key: Key('exercise-${exerciseSuggestion.id}'), + key: Key('exercise-${exercise.id}'), leading: SizedBox( width: 45, child: ExerciseImageWidget( - image: exerciseSuggestion.getMainImage, + image: exercise.getMainImage, ), ), title: Text( - exerciseSuggestion - .getTranslation(Localizations.localeOf(context).languageCode) - .name, + exercise.getTranslation(languageCode).name, ), subtitle: Text( - '${exerciseSuggestion.category!.name} / ${exerciseSuggestion.equipment.map((e) => e.name).join(', ')}', + '${exercise.category!.name} / ${exercise.equipment.map((e) => e.name).join(', ')}', ), ), emptyBuilder: (context) { @@ -141,7 +146,7 @@ class _ExerciseAutocompleterState extends State { _exercisesController.text = ''; }, ), - if (Localizations.localeOf(context).languageCode != LANGUAGE_SHORT_ENGLISH) + if (languageCode != LANGUAGE_SHORT_ENGLISH) SwitchListTile( title: Text(AppLocalizations.of(context).searchNamesInEnglish), value: _searchEnglish, diff --git a/lib/widgets/exercises/filter_modal.dart b/lib/widgets/exercises/filter_modal.dart index b80b0647..dc8de5cd 100644 --- a/lib/widgets/exercises/filter_modal.dart +++ b/lib/widgets/exercises/filter_modal.dart @@ -71,7 +71,12 @@ class _ExerciseFilterModalBodyState extends ConsumerState !value); - ref.read(exerciseStateProvider.notifier).setFilters(filters); + ref + .read(exerciseStateProvider.notifier) + .setFilters( + filters, + Localizations.localeOf(context).languageCode, + ); }); }, ); diff --git a/lib/widgets/exercises/filter_row.dart b/lib/widgets/exercises/filter_row.dart index 974702e7..15ae6b37 100644 --- a/lib/widgets/exercises/filter_row.dart +++ b/lib/widgets/exercises/filter_row.dart @@ -49,6 +49,7 @@ class _FilterRowState extends ConsumerState { .read(exerciseStateProvider.notifier) .setFilters( currentFilters.copyWith(searchTerm: text), + Localizations.localeOf(context).languageCode, ); } }); diff --git a/lib/widgets/routines/gym_mode/gym_mode.dart b/lib/widgets/routines/gym_mode/gym_mode.dart index 42beef09..a1e04856 100644 --- a/lib/widgets/routines/gym_mode/gym_mode.dart +++ b/lib/widgets/routines/gym_mode/gym_mode.dart @@ -132,7 +132,7 @@ class _GymModeState extends ConsumerState { List getContent() { final state = ref.watch(gymStateProvider); - final exercisesAsync = ref.watch(exerciseStateProvider.notifier); + final exercisesAsync = ref.read(exerciseStateProvider.notifier); final routinesProvider = context.read(); var currentElement = 1; final List out = []; diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 20619c35..bd5b38b0 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,7 @@ import FlutterMacOS import Foundation +import connectivity_plus import file_selector_macos import package_info_plus import path_provider_foundation @@ -16,6 +17,7 @@ import url_launcher_macos import video_player_avfoundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 22fb3253..7f1c4f3d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -257,6 +257,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.19.1" + connectivity_plus: + dependency: "direct main" + description: + name: connectivity_plus + sha256: "33bae12a398f841c6cda09d1064212957265869104c478e5ad51e2fb26c3973c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" + url: "https://pub.dev" + source: hosted + version: "2.0.1" convert: dependency: transitive description: @@ -329,6 +345,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" drift: dependency: "direct main" description: @@ -940,6 +964,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" node_preamble: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f889f626..fb92314e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -73,6 +73,7 @@ dependencies: riverpod_annotation: ^3.0.3 stream_transform: ^2.1.1 state_notifier: ^1.0.0 + connectivity_plus: ^7.0.0 dev_dependencies: flutter_test: diff --git a/test/core/settings_test.mocks.dart b/test/core/settings_test.mocks.dart index 208aca6e..8f80bd83 100644 --- a/test/core/settings_test.mocks.dart +++ b/test/core/settings_test.mocks.dart @@ -155,14 +155,6 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider { ) as List<_i4.Exercise>); - @override - List<_i4.Exercise> get filteredExercises => - (super.noSuchMethod( - Invocation.getter(#filteredExercises), - returnValue: <_i4.Exercise>[], - ) - as List<_i4.Exercise>); - @override Map> get exerciseByVariation => (super.noSuchMethod( @@ -215,12 +207,6 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider { returnValueForMissingStub: null, ); - @override - set filteredExercises(List<_i4.Exercise>? newFilteredExercises) => super.noSuchMethod( - Invocation.setter(#filteredExercises, newFilteredExercises), - returnValueForMissingStub: null, - ); - @override set languages(List<_i8.Language>? languages) => super.noSuchMethod( Invocation.setter(#languages, languages), @@ -231,30 +217,6 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider { bool get hasListeners => (super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool); - @override - _i18.Future setFilters(_i17.Filters? newFilters) => - (super.noSuchMethod( - Invocation.method(#setFilters, [newFilters]), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) - as _i18.Future); - - @override - void initFilters() => super.noSuchMethod( - Invocation.method(#initFilters, []), - returnValueForMissingStub: null, - ); - - @override - _i18.Future findByFilters() => - (super.noSuchMethod( - Invocation.method(#findByFilters, []), - returnValue: _i18.Future.value(), - returnValueForMissingStub: _i18.Future.value(), - ) - as _i18.Future); - @override void clear() => super.noSuchMethod( Invocation.method(#clear, []), @@ -496,24 +458,6 @@ class MockExercisesProvider extends _i1.Mock implements _i17.ExercisesProvider { ) as _i18.Future); - @override - _i18.Future> searchExercise( - String? name, { - String? languageCode = 'en', - bool? searchEnglish = false, - }) => - (super.noSuchMethod( - Invocation.method( - #searchExercise, - [name], - {#languageCode: languageCode, #searchEnglish: searchEnglish}, - ), - returnValue: _i18.Future>.value( - <_i4.Exercise>[], - ), - ) - as _i18.Future>); - @override void addListener(_i19.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), diff --git a/test/exercises/contribute_exercise_test.mocks.dart b/test/exercises/contribute_exercise_test.mocks.dart index 021fd2b7..75869f47 100644 --- a/test/exercises/contribute_exercise_test.mocks.dart +++ b/test/exercises/contribute_exercise_test.mocks.dart @@ -512,14 +512,6 @@ class MockExercisesProvider extends _i1.Mock implements _i20.ExercisesProvider { ) as List<_i6.Exercise>); - @override - List<_i6.Exercise> get filteredExercises => - (super.noSuchMethod( - Invocation.getter(#filteredExercises), - returnValue: <_i6.Exercise>[], - ) - as List<_i6.Exercise>); - @override Map> get exerciseByVariation => (super.noSuchMethod( @@ -572,12 +564,6 @@ class MockExercisesProvider extends _i1.Mock implements _i20.ExercisesProvider { returnValueForMissingStub: null, ); - @override - set filteredExercises(List<_i6.Exercise>? newFilteredExercises) => super.noSuchMethod( - Invocation.setter(#filteredExercises, newFilteredExercises), - returnValueForMissingStub: null, - ); - @override set languages(List<_i10.Language>? languages) => super.noSuchMethod( Invocation.setter(#languages, languages), @@ -588,30 +574,6 @@ class MockExercisesProvider extends _i1.Mock implements _i20.ExercisesProvider { bool get hasListeners => (super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool); - @override - _i15.Future setFilters(_i20.Filters? newFilters) => - (super.noSuchMethod( - Invocation.method(#setFilters, [newFilters]), - returnValue: _i15.Future.value(), - returnValueForMissingStub: _i15.Future.value(), - ) - as _i15.Future); - - @override - void initFilters() => super.noSuchMethod( - Invocation.method(#initFilters, []), - returnValueForMissingStub: null, - ); - - @override - _i15.Future findByFilters() => - (super.noSuchMethod( - Invocation.method(#findByFilters, []), - returnValue: _i15.Future.value(), - returnValueForMissingStub: _i15.Future.value(), - ) - as _i15.Future); - @override void clear() => super.noSuchMethod( Invocation.method(#clear, []), @@ -853,24 +815,6 @@ class MockExercisesProvider extends _i1.Mock implements _i20.ExercisesProvider { ) as _i15.Future); - @override - _i15.Future> searchExercise( - String? name, { - String? languageCode = 'en', - bool? searchEnglish = false, - }) => - (super.noSuchMethod( - Invocation.method( - #searchExercise, - [name], - {#languageCode: languageCode, #searchEnglish: searchEnglish}, - ), - returnValue: _i15.Future>.value( - <_i6.Exercise>[], - ), - ) - as _i15.Future>); - @override void addListener(_i16.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), diff --git a/test/exercises/exercises_detail_widget_test.mocks.dart b/test/exercises/exercises_detail_widget_test.mocks.dart index b3163b5e..4378fb91 100644 --- a/test/exercises/exercises_detail_widget_test.mocks.dart +++ b/test/exercises/exercises_detail_widget_test.mocks.dart @@ -99,14 +99,6 @@ class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider { ) as List<_i4.Exercise>); - @override - List<_i4.Exercise> get filteredExercises => - (super.noSuchMethod( - Invocation.getter(#filteredExercises), - returnValue: <_i4.Exercise>[], - ) - as List<_i4.Exercise>); - @override Map> get exerciseByVariation => (super.noSuchMethod( @@ -159,12 +151,6 @@ class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider { returnValueForMissingStub: null, ); - @override - set filteredExercises(List<_i4.Exercise>? newFilteredExercises) => super.noSuchMethod( - Invocation.setter(#filteredExercises, newFilteredExercises), - returnValueForMissingStub: null, - ); - @override set languages(List<_i8.Language>? languages) => super.noSuchMethod( Invocation.setter(#languages, languages), @@ -175,30 +161,6 @@ class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider { bool get hasListeners => (super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool); - @override - _i10.Future setFilters(_i9.Filters? newFilters) => - (super.noSuchMethod( - Invocation.method(#setFilters, [newFilters]), - returnValue: _i10.Future.value(), - returnValueForMissingStub: _i10.Future.value(), - ) - as _i10.Future); - - @override - void initFilters() => super.noSuchMethod( - Invocation.method(#initFilters, []), - returnValueForMissingStub: null, - ); - - @override - _i10.Future findByFilters() => - (super.noSuchMethod( - Invocation.method(#findByFilters, []), - returnValue: _i10.Future.value(), - returnValueForMissingStub: _i10.Future.value(), - ) - as _i10.Future); - @override void clear() => super.noSuchMethod( Invocation.method(#clear, []), @@ -440,24 +402,6 @@ class MockExercisesProvider extends _i1.Mock implements _i9.ExercisesProvider { ) as _i10.Future); - @override - _i10.Future> searchExercise( - String? name, { - String? languageCode = 'en', - bool? searchEnglish = false, - }) => - (super.noSuchMethod( - Invocation.method( - #searchExercise, - [name], - {#languageCode: languageCode, #searchEnglish: searchEnglish}, - ), - returnValue: _i10.Future>.value( - <_i4.Exercise>[], - ), - ) - as _i10.Future>); - @override void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), diff --git a/test/routine/routines_provider_test.mocks.dart b/test/routine/routines_provider_test.mocks.dart index e0309339..cce182d4 100644 --- a/test/routine/routines_provider_test.mocks.dart +++ b/test/routine/routines_provider_test.mocks.dart @@ -243,14 +243,6 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider { ) as List<_i6.Exercise>); - @override - List<_i6.Exercise> get filteredExercises => - (super.noSuchMethod( - Invocation.getter(#filteredExercises), - returnValue: <_i6.Exercise>[], - ) - as List<_i6.Exercise>); - @override Map> get exerciseByVariation => (super.noSuchMethod( @@ -303,12 +295,6 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider { returnValueForMissingStub: null, ); - @override - set filteredExercises(List<_i6.Exercise>? newFilteredExercises) => super.noSuchMethod( - Invocation.setter(#filteredExercises, newFilteredExercises), - returnValueForMissingStub: null, - ); - @override set languages(List<_i10.Language>? languages) => super.noSuchMethod( Invocation.setter(#languages, languages), @@ -319,30 +305,6 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider { bool get hasListeners => (super.noSuchMethod(Invocation.getter(#hasListeners), returnValue: false) as bool); - @override - _i11.Future setFilters(_i12.Filters? newFilters) => - (super.noSuchMethod( - Invocation.method(#setFilters, [newFilters]), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) - as _i11.Future); - - @override - void initFilters() => super.noSuchMethod( - Invocation.method(#initFilters, []), - returnValueForMissingStub: null, - ); - - @override - _i11.Future findByFilters() => - (super.noSuchMethod( - Invocation.method(#findByFilters, []), - returnValue: _i11.Future.value(), - returnValueForMissingStub: _i11.Future.value(), - ) - as _i11.Future); - @override void clear() => super.noSuchMethod( Invocation.method(#clear, []), @@ -584,24 +546,6 @@ class MockExercisesProvider extends _i1.Mock implements _i12.ExercisesProvider { ) as _i11.Future); - @override - _i11.Future> searchExercise( - String? name, { - String? languageCode = 'en', - bool? searchEnglish = false, - }) => - (super.noSuchMethod( - Invocation.method( - #searchExercise, - [name], - {#languageCode: languageCode, #searchEnglish: searchEnglish}, - ), - returnValue: _i11.Future>.value( - <_i6.Exercise>[], - ), - ) - as _i11.Future>); - @override void addListener(_i13.VoidCallback? listener) => super.noSuchMethod( Invocation.method(#addListener, [listener]), diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 943344bc..256ca9f0 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,7 @@ #include "generated_plugin_registrant.h" +#include #include #include #include @@ -13,6 +14,8 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); PowersyncFlutterLibsPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 63ed6d14..a75fb0a8 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + connectivity_plus file_selector_windows powersync_flutter_libs rive_common