wip finishing workout and saving model
parent
cd88b483cf
commit
5587f049e1
|
@ -1,6 +1,7 @@
|
||||||
import 'package:smoke_cess_app/interface/db_record.dart';
|
import 'package:smoke_cess_app/interface/db_record.dart';
|
||||||
import 'package:smoke_cess_app/models/mood.dart';
|
import 'package:smoke_cess_app/models/mood.dart';
|
||||||
import 'package:smoke_cess_app/models/sleep.dart';
|
import 'package:smoke_cess_app/models/sleep.dart';
|
||||||
|
import 'package:smoke_cess_app/models/workout.dart';
|
||||||
import 'package:smoke_cess_app/services/database_service.dart';
|
import 'package:smoke_cess_app/services/database_service.dart';
|
||||||
import 'package:sqflite_common/sqlite_api.dart';
|
import 'package:sqflite_common/sqlite_api.dart';
|
||||||
|
|
||||||
|
@ -28,7 +29,12 @@ class DatabaseMock implements DatabaseService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: implement database
|
Future<int> addWorkout(Workout workout) {
|
||||||
|
_workoutRecords.add(workout);
|
||||||
|
return Future.value(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Future<Database> get database => DatabaseService.instance.database;
|
Future<Database> get database => DatabaseService.instance.database;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
import 'package:smoke_cess_app/interface/db_record.dart';
|
|
||||||
|
|
||||||
class HIITWorkout implements DatabaseRecord {
|
|
||||||
Duration _workoutDuration;
|
|
||||||
String _commentBefore;
|
|
||||||
String _commentAfter;
|
|
||||||
DateTime _workoutDate;
|
|
||||||
|
|
||||||
HIITWorkout(this._workoutDuration, this._commentBefore, this._commentAfter,
|
|
||||||
this._workoutDate);
|
|
||||||
|
|
||||||
//TODO Felder anpassen
|
|
||||||
@override
|
|
||||||
factory HIITWorkout.fromMap(Map<String, dynamic> map) {
|
|
||||||
return HIITWorkout(map['_workoutDuration'], map['_commentBefore'],
|
|
||||||
map['_commentAfter'], map['_workoutDate']);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toCSV() =>
|
|
||||||
"${_workoutDate.toIso8601String()}, $_workoutDuration, $_commentBefore, $_commentAfter";
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toMap() {
|
|
||||||
return {
|
|
||||||
'workoutDuration': _workoutDuration,
|
|
||||||
'commentBefore': _commentBefore,
|
|
||||||
'commentAfter': _commentAfter,
|
|
||||||
'workoutDate': _workoutDate,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:smoke_cess_app/interface/db_record.dart';
|
||||||
|
|
||||||
|
class Workout implements DatabaseRecord {
|
||||||
|
int _motivationBefore;
|
||||||
|
int _motivationAfter;
|
||||||
|
DateTime _workoutDate;
|
||||||
|
|
||||||
|
Workout(this._motivationBefore, this._motivationAfter, this._workoutDate);
|
||||||
|
|
||||||
|
@override
|
||||||
|
factory Workout.fromMap(Map<String, dynamic> map) {
|
||||||
|
return Workout(map['_workoutDuration'], map['_motivationBefore'],
|
||||||
|
map['_motivationAfter']);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toCSV() =>
|
||||||
|
"${_workoutDate.toIso8601String()}, $_motivationBefore, $_motivationAfter";
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
'motivationBefore': _motivationBefore,
|
||||||
|
'motivationAfter': _motivationAfter,
|
||||||
|
'workoutDate': _workoutDate,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
import 'package:audioplayers/audioplayers.dart';
|
import 'package:audioplayers/audioplayers.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:smoke_cess_app/models/workout.dart';
|
||||||
import 'package:smoke_cess_app/providers/timer_provider.dart';
|
import 'package:smoke_cess_app/providers/timer_provider.dart';
|
||||||
|
import '../globals.dart' as globals;
|
||||||
|
|
||||||
class WorkoutProvider extends ChangeNotifier {
|
class WorkoutProvider extends ChangeNotifier {
|
||||||
TimerProvider timerProvider;
|
TimerProvider timerProvider;
|
||||||
|
@ -10,6 +12,8 @@ class WorkoutProvider extends ChangeNotifier {
|
||||||
final Source _beepSoundSource = AssetSource('beep.mp3');
|
final Source _beepSoundSource = AssetSource('beep.mp3');
|
||||||
bool isWorkoutStarted = false;
|
bool isWorkoutStarted = false;
|
||||||
bool isMuted = false;
|
bool isMuted = false;
|
||||||
|
int motivationBefore = 50;
|
||||||
|
int motivationAfter = 50;
|
||||||
|
|
||||||
void mutePlayer() {
|
void mutePlayer() {
|
||||||
isMuted = true;
|
isMuted = true;
|
||||||
|
@ -25,44 +29,29 @@ class WorkoutProvider extends ChangeNotifier {
|
||||||
|
|
||||||
WorkoutProvider(this.timerProvider);
|
WorkoutProvider(this.timerProvider);
|
||||||
|
|
||||||
//TODO: outsource all Maps to JSON File!
|
|
||||||
final List<String> _workoutPhases = [
|
final List<String> _workoutPhases = [
|
||||||
'Warm-Up',
|
'Warm-Up',
|
||||||
'High Intensity',
|
/*'High Intensity',
|
||||||
'Low Intensity',
|
'Low Intensity',
|
||||||
'High Intensity',
|
'High Intensity',
|
||||||
'Low Intensity',
|
'Low Intensity',
|
||||||
'High Intensity',
|
'High Intensity',
|
||||||
'Low Intensity',
|
'Low Intensity',
|
||||||
'High Intensity',
|
'High Intensity', */
|
||||||
'Cool-down'
|
'Cool-down'
|
||||||
];
|
];
|
||||||
final Map<String, Duration> _phasesDuration = {
|
|
||||||
'Warm-Up': const Duration(seconds: 5),
|
|
||||||
'High Intensity': const Duration(seconds: 4),
|
|
||||||
'Low Intensity': const Duration(seconds: 3),
|
|
||||||
'Cool-down': const Duration(seconds: 5)
|
|
||||||
};
|
|
||||||
final Map<String, Source> _phaseSongSources = {
|
|
||||||
'Warm-Up': AssetSource('warmUp.mp3'),
|
|
||||||
'High Intensity': AssetSource('workout.mp3'),
|
|
||||||
'Low Intensity': AssetSource('workout.mp3'),
|
|
||||||
'Cool-down': AssetSource('cool_down.mp3')
|
|
||||||
};
|
|
||||||
final Map<String, Color> _phaseColors = {
|
|
||||||
'Warm-Up': Colors.green,
|
|
||||||
'High Intensity': Colors.red,
|
|
||||||
'Low Intensity': Colors.orange,
|
|
||||||
'Cool-down': Colors.blue
|
|
||||||
};
|
|
||||||
int _workoutPhaseIndex = 0;
|
int _workoutPhaseIndex = 0;
|
||||||
|
|
||||||
String get currentPhase => _workoutPhases[_workoutPhaseIndex];
|
String get currentPhase => _workoutPhases[_workoutPhaseIndex];
|
||||||
Duration get currentPhaseDuration =>
|
Duration get currentPhaseDuration =>
|
||||||
_phasesDuration[currentPhase] ?? const Duration(seconds: 0);
|
_workoutPhaseSettings[currentPhase]!['duration'];
|
||||||
bool get isPhaseComplete =>
|
bool get isPhaseComplete =>
|
||||||
timerProvider.elapsedSeconds - currentPhaseDuration.inSeconds == 0;
|
timerProvider.elapsedSeconds - currentPhaseDuration.inSeconds == 0;
|
||||||
Color get currentPhaseColor => _phaseColors[currentPhase] ?? Colors.blue;
|
Color get currentPhaseColor => _workoutPhaseSettings[currentPhase]!['color'];
|
||||||
|
AssetSource get currentPhaseSource =>
|
||||||
|
_workoutPhaseSettings[currentPhase]!['source'];
|
||||||
|
bool get isWorkoutComplete =>
|
||||||
|
_workoutPhaseIndex == _workoutPhases.length - 1 && isPhaseComplete;
|
||||||
|
|
||||||
void nextPhase() {
|
void nextPhase() {
|
||||||
_audioPlayer.stop();
|
_audioPlayer.stop();
|
||||||
|
@ -70,10 +59,11 @@ class WorkoutProvider extends ChangeNotifier {
|
||||||
_audioPlayer.play(_beepSoundSource);
|
_audioPlayer.play(_beepSoundSource);
|
||||||
_workoutPhaseIndex += 1;
|
_workoutPhaseIndex += 1;
|
||||||
_audioPlayer.onPlayerComplete.listen((event) {
|
_audioPlayer.onPlayerComplete.listen((event) {
|
||||||
_audioPlayer.play(_phaseSongSources[currentPhase]!);
|
_audioPlayer.play(currentPhaseSource);
|
||||||
timerProvider.startTimer(currentPhaseDuration);
|
timerProvider.startTimer(currentPhaseDuration);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
//workout completed
|
||||||
_audioPlayer.play(_finishedSoundSource);
|
_audioPlayer.play(_finishedSoundSource);
|
||||||
stopWorkout();
|
stopWorkout();
|
||||||
}
|
}
|
||||||
|
@ -83,16 +73,45 @@ class WorkoutProvider extends ChangeNotifier {
|
||||||
isWorkoutStarted = true;
|
isWorkoutStarted = true;
|
||||||
_audioPlayer.play(_beepSoundSource);
|
_audioPlayer.play(_beepSoundSource);
|
||||||
_audioPlayer.onPlayerComplete.listen((event) {
|
_audioPlayer.onPlayerComplete.listen((event) {
|
||||||
_audioPlayer.play(_phaseSongSources[currentPhase]!);
|
_audioPlayer.play(currentPhaseSource);
|
||||||
timerProvider.startTimer(currentPhaseDuration);
|
timerProvider.startTimer(currentPhaseDuration);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopWorkout() {
|
void stopWorkout() {
|
||||||
isWorkoutStarted = false;
|
isWorkoutStarted = false;
|
||||||
_workoutPhaseIndex = 0;
|
//_workoutPhaseIndex = 0;
|
||||||
_audioPlayer.stop();
|
_audioPlayer.stop();
|
||||||
timerProvider.stopTimer();
|
timerProvider.stopTimer();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void saveWorkout() {
|
||||||
|
Workout workout =
|
||||||
|
Workout(motivationBefore, motivationAfter, DateTime.now());
|
||||||
|
globals.databaseService.addWorkout(workout);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Map<String, dynamic>> _workoutPhaseSettings = {
|
||||||
|
'Warm-Up': {
|
||||||
|
'duration': const Duration(seconds: 5),
|
||||||
|
'source': AssetSource('warmUp.mp3'),
|
||||||
|
'color': Colors.green
|
||||||
|
},
|
||||||
|
'High Intensity': {
|
||||||
|
'duration': const Duration(seconds: 4),
|
||||||
|
'source': AssetSource('workout.mp3'),
|
||||||
|
'color': Colors.red
|
||||||
|
},
|
||||||
|
'Low Intensity': {
|
||||||
|
'duration': const Duration(seconds: 3),
|
||||||
|
'source': AssetSource('workout.mp3'),
|
||||||
|
'color': Colors.orange
|
||||||
|
},
|
||||||
|
'Cool-down': {
|
||||||
|
'duration': const Duration(seconds: 5),
|
||||||
|
'source': AssetSource('cool_down.mp3'),
|
||||||
|
'color': Colors.blue
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
import 'package:smoke_cess_app/models/mood.dart';
|
import 'package:smoke_cess_app/models/mood.dart';
|
||||||
|
import 'package:smoke_cess_app/models/workout.dart';
|
||||||
import 'package:sqflite/sqflite.dart';
|
import 'package:sqflite/sqflite.dart';
|
||||||
// ignore: depend_on_referenced_packages
|
// ignore: depend_on_referenced_packages
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
@ -62,6 +63,11 @@ class DatabaseService {
|
||||||
Database db = await instance.database;
|
Database db = await instance.database;
|
||||||
return await db.insert('sleep', sleep.toMap());
|
return await db.insert('sleep', sleep.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<int> addWorkout(Workout workout) async {
|
||||||
|
Database db = await instance.database;
|
||||||
|
return await db.insert('workout', workout.toMap());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _createMoodTable = '''
|
String _createMoodTable = '''
|
||||||
|
@ -100,9 +106,6 @@ String _createWorkoutTable = '''
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
date TEXT,
|
date TEXT,
|
||||||
motivationBefore INTEGER,
|
motivationBefore INTEGER,
|
||||||
commentBefore TEXT,
|
|
||||||
motivationAfter INTEGER,
|
motivationAfter INTEGER,
|
||||||
commentAfter TEXT,
|
|
||||||
completed INTEGER
|
|
||||||
)
|
)
|
||||||
''';
|
''';
|
||||||
|
|
|
@ -2,12 +2,29 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:smoke_cess_app/providers/input_provider.dart';
|
import 'package:smoke_cess_app/providers/input_provider.dart';
|
||||||
import 'package:smoke_cess_app/widgets/slider.dart';
|
import 'package:smoke_cess_app/widgets/slider.dart';
|
||||||
import 'package:smoke_cess_app/widgets/text_formfield.dart';
|
|
||||||
|
Future showMotivationPopup(
|
||||||
|
BuildContext context, Function onSave, String title) async {
|
||||||
|
return await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return ChangeNotifierProvider(
|
||||||
|
create: (context) => InputProvider(),
|
||||||
|
child: TimerStartStopPopup(
|
||||||
|
title: title,
|
||||||
|
onSaveAction: onSave,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class TimerStartStopPopup extends StatelessWidget {
|
class TimerStartStopPopup extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
|
final Function onSaveAction;
|
||||||
const TimerStartStopPopup({Key? key, required this.title}) : super(key: key);
|
const TimerStartStopPopup(
|
||||||
|
{Key? key, required this.title, required this.onSaveAction})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -24,10 +41,11 @@ class TimerStartStopPopup extends StatelessWidget {
|
||||||
child: MySlider(),
|
child: MySlider(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
const MyTextFormField('Beschreibe deinen Motivation'),
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () =>
|
onPressed: () {
|
||||||
Navigator.pop(context, inputProvider.sliderValue),
|
onSaveAction(inputProvider.sliderValue);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
child: const Text('Speichern'))
|
child: const Text('Speichern'))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -5,24 +5,41 @@ import 'package:provider/provider.dart';
|
||||||
import 'package:smoke_cess_app/providers/workout_provider.dart';
|
import 'package:smoke_cess_app/providers/workout_provider.dart';
|
||||||
import 'package:smoke_cess_app/widgets/timer_widget.dart';
|
import 'package:smoke_cess_app/widgets/timer_widget.dart';
|
||||||
|
|
||||||
import '../providers/input_provider.dart';
|
|
||||||
import '../providers/timer_provider.dart';
|
import '../providers/timer_provider.dart';
|
||||||
import 'popup_for_start_and_stop.dart';
|
import 'popup_for_start_and_stop.dart';
|
||||||
|
|
||||||
class WorkoutTimerWidget extends StatelessWidget {
|
class WorkoutTimerWidget extends StatelessWidget {
|
||||||
const WorkoutTimerWidget({super.key});
|
const WorkoutTimerWidget({super.key});
|
||||||
|
|
||||||
void _onStartButtonPressed(BuildContext context) {}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
TimerProvider timerProvider = context.watch<TimerProvider>();
|
TimerProvider timerProvider = context.watch<TimerProvider>();
|
||||||
WorkoutProvider workoutProvider = context.watch<WorkoutProvider>();
|
WorkoutProvider workoutProvider = context.watch<WorkoutProvider>();
|
||||||
|
|
||||||
if (workoutProvider.isPhaseComplete) {
|
if (workoutProvider.isPhaseComplete && workoutProvider.isWorkoutStarted) {
|
||||||
Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase());
|
Timer(const Duration(milliseconds: 1), () => workoutProvider.nextPhase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleStartStopWorkout() async {
|
||||||
|
if (!workoutProvider.isWorkoutStarted) {
|
||||||
|
await showMotivationPopup(
|
||||||
|
context,
|
||||||
|
(double value) => workoutProvider.motivationBefore = value.toInt(),
|
||||||
|
'Motivation vor dem Training');
|
||||||
|
workoutProvider.startWorkout();
|
||||||
|
} else {
|
||||||
|
workoutProvider.stopWorkout();
|
||||||
|
await showMotivationPopup(
|
||||||
|
context,
|
||||||
|
(double value) => workoutProvider.motivationAfter = value.toInt(),
|
||||||
|
'Motivation nach dem Training');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workoutProvider.isWorkoutComplete) {
|
||||||
|
handleStartStopWorkout();
|
||||||
|
}
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
@ -49,23 +66,7 @@ class WorkoutTimerWidget extends StatelessWidget {
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: !workoutProvider.isWorkoutStarted
|
onPressed: handleStartStopWorkout,
|
||||||
? () async {
|
|
||||||
double sliderValue = await showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return ChangeNotifierProvider(
|
|
||||||
create: (context) => InputProvider(),
|
|
||||||
child: const TimerStartStopPopup(
|
|
||||||
title: 'Motivation vor dem Training',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
print(sliderValue);
|
|
||||||
workoutProvider.startWorkout();
|
|
||||||
}
|
|
||||||
: () => workoutProvider.stopWorkout(),
|
|
||||||
child: Text(timerProvider.started ? 'Stop' : 'Start'))
|
child: Text(timerProvider.started ? 'Stop' : 'Start'))
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue