cpd_2022_zi/lib/pages/interval_page.dart

237 lines
7.5 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
2023-02-26 17:33:32 +01:00
import 'package:provider/provider.dart';
import 'package:smoke_cess_app/providers/timer_provider.dart';
import 'package:smoke_cess_app/providers/workout_provider.dart';
2023-02-21 22:33:03 +01:00
import 'package:smoke_cess_app/widgets/popup_for_start_and_stop.dart';
import 'package:smoke_cess_app/widgets/timer_widget.dart';
import 'package:smoke_cess_app/widgets/workout_timer_widget.dart';
2023-02-26 17:33:32 +01:00
import '../providers/input_provider.dart';
class IntervalTimerPage extends StatefulWidget {
const IntervalTimerPage({Key? key}) : super(key: key);
2023-02-14 14:13:32 +01:00
@override
_IntervalTimerPageState createState() => _IntervalTimerPageState();
}
class _IntervalTimerPageState extends State<IntervalTimerPage> {
2023-02-26 00:32:58 +01:00
final Duration _warmupDuration = const Duration(seconds: 5);
final Duration _cooldownDuration = const Duration(seconds: 5);
final Duration _highIntensityDuration = const Duration(seconds: 4);
final Duration _lowIntensityDuration = const Duration(seconds: 3);
late Duration _totalDuration = const Duration(minutes: 35);
2023-02-20 21:12:48 +01:00
AudioPlayer warmUpPlayer = AudioPlayer();
AudioPlayer workoutPlayer = AudioPlayer();
AudioPlayer coolDownPlayer = AudioPlayer();
2023-02-26 00:32:58 +01:00
final AudioCache _audioCache = AudioCache();
final int _numHighIntensityBlocks = 4;
final int _numLowIntensityBlocks = 3;
Timer? _timer;
int _currentBlock = 0;
Duration _currentDuration = const Duration();
bool _isPaused = true;
2023-02-16 02:08:15 +01:00
@override
void initState() {
_currentDuration = _warmupDuration;
2023-02-16 02:08:15 +01:00
super.initState();
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
2023-02-16 02:08:15 +01:00
}
2023-02-21 22:33:03 +01:00
void _startTimer() async {
await showDialog(
context: context,
builder: (BuildContext context) {
2023-02-26 17:33:32 +01:00
return ChangeNotifierProvider(
create: (context) => InputProvider(),
child: const TimerStartStopPopup(
title: 'Motivation vor dem Training',
));
2023-02-21 22:33:03 +01:00
},
);
_isPaused = false;
2023-02-26 00:32:58 +01:00
Source source = AssetSource('go.mp3');
await AudioPlayer().play(source);
2023-02-21 22:33:03 +01:00
_timer = Timer.periodic(const Duration(seconds: 1), (_) => _tick());
Future.delayed(const Duration(seconds: 1)).then((value) {
2023-02-20 21:12:48 +01:00
_playWarmUpMusic();
});
}
void _resetTimer() {
() async {
2023-02-21 23:28:31 +01:00
await coolDownPlayer.stop();
await warmUpPlayer.stop();
await workoutPlayer.stop();
}();
_isPaused = true;
_timer?.cancel();
_currentBlock = 0;
_currentDuration = _warmupDuration;
_totalDuration = const Duration(minutes: 35);
setState(() {});
2023-02-21 22:33:03 +01:00
showDialog(
context: context,
builder: (BuildContext context) {
2023-02-22 13:32:23 +01:00
return const TimerStartStopPopup(
2023-02-21 22:33:03 +01:00
title: 'Motivation nach dem Training',
);
},
);
}
2023-02-20 21:12:48 +01:00
Future<void> _playWarmUpMusic() async {
2023-02-26 00:32:58 +01:00
Source source = AssetSource('warmUp.mp3');
2023-02-20 21:12:48 +01:00
await warmUpPlayer.setReleaseMode(ReleaseMode.loop);
2023-02-26 00:32:58 +01:00
await warmUpPlayer.play(source);
}
2023-02-20 21:12:48 +01:00
Future<void> _playWorkoutMusic() async {
2023-02-21 23:28:31 +01:00
await warmUpPlayer.stop();
Future.delayed(const Duration(microseconds: 600)).then((value) async {
2023-02-26 00:32:58 +01:00
Source source = AssetSource('workout.mp3');
await workoutPlayer.setReleaseMode(ReleaseMode.loop);
2023-02-26 00:32:58 +01:00
await workoutPlayer.play(source);
});
}
Future<void> _intervalChange() async {
2023-02-26 00:32:58 +01:00
Source source = AssetSource('beep.mp3');
await AudioPlayer().play(source);
}
void _tick() {
setState(() {
_currentDuration = Duration(
seconds: _currentDuration.inSeconds - 1,
);
_totalDuration = Duration(
seconds: _totalDuration.inSeconds - 1,
);
if (_currentDuration.inSeconds < 1) {
if (_currentBlock < _numHighIntensityBlocks + _numLowIntensityBlocks) {
_intervalChange();
if (_currentBlock == 0) {
2023-02-20 21:12:48 +01:00
_playWorkoutMusic();
}
_currentBlock++;
if (_currentBlock % 2 == 1) {
_currentDuration = _highIntensityDuration;
} else {
_currentDuration = _lowIntensityDuration;
}
} else if (_currentBlock < _numHighIntensityBlocks * 2) {
_intervalChange();
_currentBlock++;
_currentDuration = _cooldownDuration;
() async {
2023-02-21 23:28:31 +01:00
await workoutPlayer.stop();
2023-02-26 00:32:58 +01:00
Source source = AssetSource('cool_down.mp3');
await coolDownPlayer.setReleaseMode(ReleaseMode.loop);
2023-02-26 00:32:58 +01:00
await coolDownPlayer.play(source);
}();
} else {
() async {
Future.delayed(const Duration(microseconds: 900))
.then((value) async {
2023-02-26 00:32:58 +01:00
Source source = AssetSource('finish.mp3');
await AudioPlayer().play(source);
});
}();
_resetTimer();
}
}
});
}
String _formatDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, '0');
final minutes = twoDigits(duration.inMinutes.remainder(60));
final seconds = twoDigits(duration.inSeconds.remainder(60));
return '$minutes:$seconds';
}
String _formatTotalDuration(Duration duration) {
final minutes = duration.inMinutes;
final seconds = duration.inSeconds.remainder(60);
return _formatDuration(Duration(minutes: minutes, seconds: seconds));
}
@override
Widget build(BuildContext context) {
TimerProvider timerProvider = TimerProvider();
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => timerProvider),
ChangeNotifierProvider(
create: (context) => WorkoutProvider(timerProvider))
],
child: WorkoutTimerWidget(),
);
ChangeNotifierProvider(
create: (context) => TimerProvider(),
child: TimerWidget(
duration: Duration(seconds: 5),
));
2023-02-26 17:33:32 +01:00
return Center(
child: ChangeNotifierProvider(
create: (context) => InputProvider(),
child: Column(
2023-02-26 17:33:32 +01:00
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
_currentBlock == 0
? 'Warm-up'
: _currentBlock % 2 == 1
? 'High Intensity'
: _currentBlock < _numHighIntensityBlocks * 2
? 'Low Intensity'
: 'Cool-down',
style: const TextStyle(fontSize: 32.0),
),
const SizedBox(height: 16.0),
Text(
_formatDuration(_currentDuration),
style: const TextStyle(fontSize: 80.0),
),
const SizedBox(height: 32.0),
Text(
'Total: ${_formatTotalDuration(_totalDuration)}',
style: const TextStyle(fontSize: 24.0),
),
const SizedBox(height: 32.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(_isPaused
? Icons.play_arrow_rounded
: Icons.stop_rounded),
iconSize: 48.0,
onPressed: () {
if (_isPaused) {
_startTimer();
} else {
_resetTimer();
}
},
),
// ),
],
),
],
)));
}
}