0.5.7 - Sleep timer

This commit is contained in:
exttex 2020-10-15 22:10:17 +02:00
parent 2ad4c169b8
commit 396b51e90f
7 changed files with 158 additions and 32 deletions

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/api/definitions.dart';
import 'package:freezer/ui/details_screens.dart';
@ -41,6 +43,12 @@ class Cache {
@JsonKey(defaultValue: SortType.DEFAULT)
SortType trackSort;
//Sleep timer
@JsonKey(ignore: true)
DateTime sleepTimerTime;
@JsonKey(ignore: true)
StreamSubscription sleepTimer;
//If download threads warning was shown
@JsonKey(defaultValue: false)
bool threadsWarning;

View File

@ -336,6 +336,7 @@ class AudioPlayerTask extends BackgroundAudioTask {
//Restore position on play
if (_lastPosition != null) {
onSeekTo(_lastPosition);
_lastPosition = null;
}
}

View File

@ -238,6 +238,13 @@ const language_en_us = {
//0.5.6 Strings:
"Create .nomedia files": "Create .nomedia files",
"To prevent gallery being filled with album art": "To prevent gallery being filled with album art"
"To prevent gallery being filled with album art": "To prevent gallery being filled with album art",
//0.5.7 Strings:
"Sleep timer": "Sleep timer",
"Minutes:": "Minutes:",
"Hours:": "Hours:",
"Cancel current timer": "Cancel current timer",
"Current timer ends at": "Current timer ends at"
}
};

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audio_service/audio_service.dart';
@ -8,6 +10,7 @@ import 'package:freezer/api/download.dart';
import 'package:freezer/ui/details_screens.dart';
import 'package:freezer/ui/error.dart';
import 'package:freezer/translations.i18n.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:share/share.dart';
import '../api/definitions.dart';
@ -519,10 +522,123 @@ class MenuSheet {
},
);
Widget sleepTimer() => ListTile(
title: Text('Sleep timer'.i18n),
leading: Icon(Icons.access_time),
onTap: () async {
showDialog(
context: context,
builder: (context) {
return SleepTimerDialog();
}
);
},
);
void _close() => Navigator.of(context).pop();
}
class SleepTimerDialog extends StatefulWidget {
@override
_SleepTimerDialogState createState() => _SleepTimerDialogState();
}
class _SleepTimerDialogState extends State<SleepTimerDialog> {
int hours = 0;
int minutes = 30;
String _endTime() {
return '${cache.sleepTimerTime.hour.toString().padLeft(2, '0')}:${cache.sleepTimerTime.minute.toString().padLeft(2, '0')}';
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Sleep timer'.i18n),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Hours:'.i18n),
NumberPicker.integer(
initialValue: hours,
minValue: 0,
maxValue: 69,
onChanged: (v) => setState(() => hours = v),
highlightSelectedValue: true,
),
],
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Minutes:'.i18n),
NumberPicker.integer(
initialValue: minutes,
minValue: 0,
maxValue: 60,
onChanged: (v) => setState(() => minutes = v),
highlightSelectedValue: true
),
],
),
],
),
Container(height: 4.0),
if (cache.sleepTimerTime != null)
Text(
'Current timer ends at'.i18n + ': ' +_endTime(),
textAlign: TextAlign.center,
)
],
),
actions: [
FlatButton(
child: Text('Dismiss'.i18n),
onPressed: () {
Navigator.of(context).pop();
},
),
if (cache.sleepTimer != null)
FlatButton(
child: Text('Cancel current timer'.i18n),
onPressed: () {
cache.sleepTimer.cancel();
cache.sleepTimer = null;
cache.sleepTimerTime = null;
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Save'.i18n),
onPressed: () {
Duration duration = Duration(hours: hours, minutes: minutes);
if (cache.sleepTimer != null) {
cache.sleepTimer.cancel();
}
//Create timer
cache.sleepTimer = Stream.fromFuture(Future.delayed(duration)).listen((_) {
AudioService.pause();
cache.sleepTimer.cancel();
cache.sleepTimerTime = null;
cache.sleepTimer = null;
});
cache.sleepTimerTime = DateTime.now().add(duration);
Navigator.of(context).pop();
},
),
],
);
}
}
class SelectPlaylistDialog extends StatefulWidget {
final Track track;

View File

@ -197,7 +197,7 @@ class _PlayerScreenHorizontalState extends State<PlayerScreenHorizontal> {
onPressed: () {
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
MenuSheet m = MenuSheet(context);
m.defaultTrackMenu(t);
m.defaultTrackMenu(t, options: [m.sleepTimer()]);
},
)
],
@ -331,7 +331,7 @@ class _PlayerScreenVerticalState extends State<PlayerScreenVertical> {
onPressed: () {
Track t = Track.fromMediaItem(AudioService.currentMediaItem);
MenuSheet m = MenuSheet(context);
m.defaultTrackMenu(t);
m.defaultTrackMenu(t, options: [m.sleepTimer()]);
},
)
],

View File

@ -42,7 +42,7 @@ packages:
name: audio_session
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.7"
version: "0.0.9"
boolean_selector:
dependency: transitive
description:
@ -161,7 +161,7 @@ packages:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "3.4.1"
version: "3.5.0"
collection:
dependency: "direct main"
description:
@ -175,7 +175,7 @@ packages:
name: connectivity
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.9+3"
version: "0.4.9+5"
connectivity_for_web:
dependency: transitive
description:
@ -288,13 +288,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.1"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file:
dependency: transitive
description:
@ -355,7 +348,7 @@ packages:
name: flutter_local_notifications
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4+5"
version: "1.5.0+1"
flutter_local_notifications_platform_interface:
dependency: transitive
description:
@ -433,7 +426,7 @@ packages:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0+3"
version: "0.14.0+4"
http:
dependency: transitive
description:
@ -462,6 +455,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.5"
infinite_listview:
dependency: transitive
description:
name: infinite_listview
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1+1"
intl:
dependency: "direct main"
description:
@ -567,6 +567,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
numberpicker:
dependency: "direct main"
description:
name: numberpicker
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
octo_image:
dependency: transitive
description:
@ -608,7 +615,7 @@ packages:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.18"
version: "1.6.10"
path_provider_ex:
dependency: "direct main"
description:
@ -637,13 +644,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+1"
pedantic:
dependency: transitive
description:
@ -872,7 +872,7 @@ packages:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "5.7.2"
version: "5.7.4"
url_launcher_linux:
dependency: transitive
description:
@ -936,13 +936,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.3"
xdg_directories:
dependency: transitive
description:

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.5.6+1
version: 0.5.7+1
environment:
sdk: ">=2.8.0 <3.0.0"
@ -68,6 +68,7 @@ dependencies:
url_launcher: ^5.7.2
uni_links: ^0.4.0
share: ^0.6.5+2
numberpicker: ^1.2.1
audio_session: ^0.0.9
audio_service: