sound works and intervall needs improfmends

main
Parricc35 2023-02-19 15:44:41 +01:00
parent 4b2e900bda
commit fb31d1db2c
25 changed files with 273 additions and 110 deletions

BIN
assets/beep.mp3 100644

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 544 B

View File

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View File

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 721 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -24,7 +24,7 @@ class MyHomePageState extends State<MyHomePage> {
static const List<Widget> _widgetOptions = <Widget>[ static const List<Widget> _widgetOptions = <Widget>[
MoodPage(), MoodPage(),
SleepPage(), SleepPage(),
StopWatchTimerPage(), IntervalTimerPage(),
RelapsePage(), RelapsePage(),
SettingsPage(), SettingsPage(),
]; ];

View File

@ -1,136 +1,160 @@
import 'dart:async'; import 'dart:async';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:smoke_cess_app/service/settings_service.dart';
import 'package:smoke_cess_app/widgets/timer_button.dart';
class StopWatchTimerPage extends StatefulWidget { class IntervalTimerPage extends StatefulWidget {
const StopWatchTimerPage({super.key}); const IntervalTimerPage({Key? key}) : super(key: key);
@override @override
StopWatchTimerPageState createState() => StopWatchTimerPageState(); _IntervalTimerPageState createState() => _IntervalTimerPageState();
} }
class StopWatchTimerPageState extends State<StopWatchTimerPage> { class _IntervalTimerPageState extends State<IntervalTimerPage> {
SettingsService settings = SettingsService(); final Duration _warmupDuration = const Duration(seconds: 5);
Duration duration = const Duration(minutes: 1); final Duration _cooldownDuration = const Duration(seconds: 5);
Timer? timer; final Duration _highIntensityDuration = const Duration(seconds: 4);
final Duration _lowIntensityDuration = const Duration(seconds: 3);
bool countDown = true; late Duration _totalDuration = const Duration(seconds: 35);
final int _numHighIntensityBlocks = 4;
final int _numLowIntensityBlocks = 3;
Timer? _timer;
int _currentBlock = 0;
Duration _currentDuration = const Duration();
bool _isPaused = true;
@override @override
void initState() { void initState() {
setDurationWithSetting(); _currentDuration = _warmupDuration;
super.initState(); super.initState();
} }
void setDurationWithSetting() { @override
settings.getIntSetting('workout_duration_minutes').then((workoutMinutes) => void dispose() {
{setState(() => duration = Duration(minutes: workoutMinutes ?? 10))}); _timer?.cancel();
super.dispose();
} }
void reset() { void _startTimer() {
if (countDown) { _isPaused = false;
setDurationWithSetting(); _timer = Timer.periodic(const Duration(seconds: 1), (_) => _tick());
} else {
setState(() => duration = const Duration());
}
} }
void startTimer() { void _pauseTimer() {
timer = Timer.periodic(const Duration(seconds: 1), (_) => addTime()); _isPaused = true;
_timer?.cancel();
} }
void addTime() { void _resetTimer() {
final addSeconds = countDown ? -1 : 1; _isPaused = true;
_timer?.cancel();
_currentBlock = 0;
_currentDuration = _warmupDuration;
_totalDuration = const Duration(minutes: 35);
setState(() {});
}
Future<void> _playSoundEffect() async {
final player = AudioPlayer();
await player.play(UrlSource('assets/beep.mp3'));
}
void _tick() {
setState(() { setState(() {
final seconds = duration.inSeconds + addSeconds; _currentDuration = Duration(
if (seconds < 0) { seconds: _currentDuration.inSeconds - 1,
timer?.cancel(); );
_totalDuration = Duration(
seconds: _totalDuration.inSeconds - 1,
);
if (_currentDuration.inSeconds == 0) {
_playSoundEffect();
}
if (_currentDuration.inSeconds < 0) {
if (_currentBlock == 0) {
// Start high intensity blocks.
_currentBlock++;
_currentDuration = _highIntensityDuration;
} else if (_currentBlock <= _numHighIntensityBlocks) {
// Start low intensity blocks.
_currentBlock++;
_currentDuration = _lowIntensityDuration;
} else if (_currentBlock <=
_numHighIntensityBlocks + _numLowIntensityBlocks) {
// Start high intensity blocks again.
_currentBlock++;
_currentDuration = _highIntensityDuration;
} else { } else {
duration = Duration(seconds: seconds); // End workout.
_currentDuration = _cooldownDuration;
_pauseTimer();
}
} }
}); });
} }
void stopTimer({bool resets = true}) { String _formatDuration(Duration duration) {
if (resets) {
reset();
}
setState(() => timer?.cancel());
}
@override
Widget build(BuildContext context) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buildTime(),
const SizedBox(
height: 80,
),
buildButtons()
],
),
);
Widget buildTime() {
String twoDigits(int n) => n.toString().padLeft(2, '0'); String twoDigits(int n) => n.toString().padLeft(2, '0');
final minutes = twoDigits(duration.inMinutes.remainder(60)); final minutes = twoDigits(duration.inMinutes.remainder(60));
final seconds = twoDigits(duration.inSeconds.remainder(60)); final seconds = twoDigits(duration.inSeconds.remainder(60));
return Row(mainAxisAlignment: MainAxisAlignment.center, children: [ return '$minutes:$seconds';
const SizedBox(
width: 8,
),
buildTimeCard(time: minutes, header: 'MINUTEN'),
const SizedBox(
width: 8,
),
buildTimeCard(time: seconds, header: 'SEKUNDEN'),
]);
} }
Widget buildTimeCard({required String time, required String header}) => String _formatTotalDuration(Duration duration) {
Column( final minutes = duration.inMinutes;
final seconds = duration.inSeconds.remainder(60);
return _formatDuration(Duration(minutes: minutes, seconds: seconds));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Interval Timer'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Container( Text(
padding: const EdgeInsets.all(8), _currentBlock == 0
decoration: BoxDecoration( ? 'Warm-up'
color: Colors.white, borderRadius: BorderRadius.circular(20)), : _currentBlock <= _numHighIntensityBlocks
child: Text( ? 'High Intensity'
time, : 'Low Intensity',
style: const TextStyle( style: const TextStyle(fontSize: 32.0),
fontWeight: FontWeight.bold,
color: Colors.black,
fontSize: 50),
), ),
const SizedBox(height: 16.0),
Text(
_formatDuration(_currentDuration),
style: const TextStyle(fontSize: 80.0),
), ),
const SizedBox( const SizedBox(height: 32.0),
height: 24, Text(
'Total: ${_formatTotalDuration(_totalDuration)}',
style: const TextStyle(fontSize: 24.0),
), ),
Text(header, style: const TextStyle(color: Colors.black45)), 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 {
_pauseTimer();
_resetTimer();
}
},
),
// ),
], ],
);
Widget buildButtons() {
final isRunning = timer == null ? false : timer!.isActive;
final isCompleted = duration.inSeconds == 0;
return isRunning || isCompleted
? TimerButton(
onClicked: stopTimer,
icon: const Icon(
Icons.stop,
size: 50,
color: Colors.white,
), ),
color: Colors.red) ],
: TimerButton( )));
onClicked: startTimer,
icon: const Icon(
Icons.play_arrow,
size: 50,
color: Colors.white,
),
color: Colors.green);
} }
} }

View File

@ -3,10 +3,6 @@ import 'package:shared_preferences/shared_preferences.dart';
class SettingsService { class SettingsService {
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance(); final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
SettingsService() {
setIntSetting('workout_duration_minutes', 5);
}
void setStringSetting(String settingKey, String settingValue) => void setStringSetting(String settingKey, String settingValue) =>
_prefs.then((pref) => pref.setString(settingKey, settingValue)); _prefs.then((pref) => pref.setString(settingKey, settingValue));

View File

@ -8,6 +8,62 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.9.0" version: "2.9.0"
audio_session:
dependency: transitive
description:
name: audio_session
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.13"
audioplayers:
dependency: "direct main"
description:
name: audioplayers
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
audioplayers_android:
dependency: transitive
description:
name: audioplayers_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
audioplayers_darwin:
dependency: transitive
description:
name: audioplayers_darwin
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
audioplayers_linux:
dependency: transitive
description:
name: audioplayers_linux
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
audioplayers_platform_interface:
dependency: transitive
description:
name: audioplayers_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
audioplayers_web:
dependency: transitive
description:
name: audioplayers_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
audioplayers_windows:
dependency: transitive
description:
name: audioplayers_windows
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -36,6 +92,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.16.0" version: "1.16.0"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -86,6 +149,20 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
http:
dependency: transitive
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.5"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.2"
js: js:
dependency: transitive dependency: transitive
description: description:
@ -93,6 +170,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.4" version: "0.6.4"
just_audio:
dependency: "direct main"
description:
name: just_audio
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.31"
just_audio_platform_interface:
dependency: transitive
description:
name: just_audio_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.0"
just_audio_web:
dependency: transitive
description:
name: just_audio_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.7"
lints: lints:
dependency: transitive dependency: transitive
description: description:
@ -128,6 +226,27 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.8.2"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.12"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.22"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -170,6 +289,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
rxdart:
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
source: hosted
version: "0.27.7"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -266,6 +392,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.12" version: "0.4.12"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
uuid:
dependency: transitive
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.7"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:

View File

@ -3,7 +3,7 @@ description: A new Flutter project.
# The following line prevents the package from being accidentally published to # The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages. # pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: "none" # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application. # The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43 # A version number is three numbers separated by dots, like 1.2.43
@ -20,7 +20,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: '>=2.18.2 <3.0.0' sdk: ">=2.18.2 <3.0.0"
# Dependencies specify other packages that your package needs in order to work. # Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions # To automatically upgrade your package dependencies to the latest versions
@ -36,6 +36,8 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
shared_preferences: ^2.0.17 shared_preferences: ^2.0.17
audioplayers: ^3.0.1
just_audio: ^0.9.31
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
@ -59,7 +61,8 @@ flutter:
uses-material-design: true uses-material-design: true
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: assets:
- beep.mp3
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg