lyrics wip: better visualizer
player_screen: always white statusbar icons
This commit is contained in:
parent
20b92334ba
commit
5edcc8648c
|
@ -20,7 +20,6 @@
|
|||
<uses-feature android:name="android.software.LEANBACK" android:required="true"/>
|
||||
|
||||
<application
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Freezer"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:fluttertoast/fluttertoast.dart';
|
|||
import 'package:freezer/api/cache.dart';
|
||||
import 'package:freezer/api/deezer.dart';
|
||||
import 'package:freezer/api/definitions.dart';
|
||||
import 'package:freezer/api/importer.dart';
|
||||
import 'package:freezer/api/player.dart';
|
||||
import 'package:freezer/settings.dart';
|
||||
import 'package:freezer/ui/details_screens.dart';
|
||||
|
@ -18,7 +19,6 @@ import 'package:draggable_scrollbar/draggable_scrollbar.dart';
|
|||
|
||||
import 'menu.dart';
|
||||
import 'settings_screen.dart';
|
||||
import '../api/spotify.dart';
|
||||
import '../api/download.dart';
|
||||
|
||||
class LibraryAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
|
@ -134,15 +134,45 @@ class LibraryScreen extends StatelessWidget {
|
|||
leading: LeadingIcon(Icons.import_export, color: Color(0xff2ba766)),
|
||||
subtitle: Text('Import playlists from Spotify'.i18n),
|
||||
onTap: () {
|
||||
if (spotify.doneImporting != null) {
|
||||
//Show progress
|
||||
if (importer.done || importer.busy) {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => CurrentlyImportingScreen()));
|
||||
if (spotify.doneImporting) spotify.doneImporting = null;
|
||||
builder: (context) => ImporterStatusScreen()));
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => ImporterScreen()));
|
||||
//Pick importer dialog
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => SimpleDialog(
|
||||
title: Text('Importer'.i18n),
|
||||
children: [
|
||||
ListTile(
|
||||
leading: Icon(FontAwesome5.spotify),
|
||||
title: Text('Spotify v1'.i18n),
|
||||
subtitle: Text(
|
||||
'Import Spotify playlists up to 100 tracks without any login.'
|
||||
.i18n),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => SpotifyImporterV1()));
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(FontAwesome5.spotify),
|
||||
title: Text('Spotify v2'.i18n),
|
||||
subtitle: Text(
|
||||
'Import any Spotify playlist, import from own Spotify library. Requires free account.'
|
||||
.i18n),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (context) => SpotifyImporterV2()));
|
||||
},
|
||||
)
|
||||
],
|
||||
));
|
||||
},
|
||||
),
|
||||
ExpansionTile(
|
||||
|
|
|
@ -150,6 +150,67 @@ class _LyricsScreenState extends State<LyricsScreen> {
|
|||
: null),
|
||||
body: Stack(
|
||||
children: [
|
||||
//Lyrics
|
||||
_error
|
||||
?
|
||||
//Shouldn't really happen, empty lyrics have own text
|
||||
ErrorScreen()
|
||||
:
|
||||
// Loading lyrics
|
||||
_loading
|
||||
? Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [CircularProgressIndicator()],
|
||||
),
|
||||
)
|
||||
: NotificationListener(
|
||||
onNotification: (Notification notification) {
|
||||
if (_freeScroll ||
|
||||
notification is! ScrollStartNotification)
|
||||
return false;
|
||||
if (!_animatedScroll)
|
||||
setState(() => _freeScroll = true);
|
||||
return false;
|
||||
},
|
||||
child: ListView.builder(
|
||||
controller: _controller,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
0, 0, 0, settings.lyricsVisualizer ? 100 : 0),
|
||||
itemCount: lyrics.lyrics.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
color: _currentIndex == i
|
||||
? Colors.grey.withOpacity(0.25)
|
||||
: Colors.transparent,
|
||||
),
|
||||
height: height,
|
||||
child: InkWell(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
onTap: lyrics.id != null
|
||||
? () => AudioService.seekTo(
|
||||
lyrics.lyrics[i].offset)
|
||||
: null,
|
||||
child: Center(
|
||||
child: Text(
|
||||
lyrics.lyrics[i].text,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 26.0,
|
||||
fontWeight: (_currentIndex == i)
|
||||
? FontWeight.bold
|
||||
: FontWeight.normal),
|
||||
),
|
||||
))));
|
||||
},
|
||||
)),
|
||||
|
||||
//Visualizer
|
||||
if (settings.lyricsVisualizer)
|
||||
Positioned(
|
||||
|
@ -160,89 +221,21 @@ class _LyricsScreenState extends State<LyricsScreen> {
|
|||
stream: playerHelper.visualizerStream,
|
||||
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||
List<double> data = snapshot.data ?? [];
|
||||
double width =
|
||||
MediaQuery.of(context).size.width / data.length -
|
||||
0.25;
|
||||
double width = MediaQuery.of(context).size.width /
|
||||
data.length; //- 0.25;
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: List.generate(
|
||||
data.length,
|
||||
(i) => AnimatedContainer(
|
||||
duration: Duration(milliseconds: 130),
|
||||
color: Theme.of(context).primaryColor,
|
||||
color: settings.primaryColor,
|
||||
height: data[i] * 100,
|
||||
width: width,
|
||||
)),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
//Lyrics
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
0, 0, 0, settings.lyricsVisualizer ? 100 : 0),
|
||||
child: _error
|
||||
?
|
||||
//Shouldn't really happen, empty lyrics have own text
|
||||
ErrorScreen()
|
||||
:
|
||||
// Loading
|
||||
_loading
|
||||
? Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [CircularProgressIndicator()],
|
||||
),
|
||||
)
|
||||
: NotificationListener(
|
||||
onNotification: (Notification notification) {
|
||||
if (_freeScroll ||
|
||||
notification is! ScrollStartNotification)
|
||||
return false;
|
||||
if (!_animatedScroll)
|
||||
setState(() => _freeScroll = true);
|
||||
return false;
|
||||
},
|
||||
child: ListView.builder(
|
||||
controller: _controller,
|
||||
itemCount: lyrics.lyrics.length,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
color: _currentIndex == i
|
||||
? Colors.grey.withOpacity(0.25)
|
||||
: Colors.transparent,
|
||||
),
|
||||
height: height,
|
||||
child: InkWell(
|
||||
borderRadius:
|
||||
BorderRadius.circular(8.0),
|
||||
onTap: lyrics.id != null
|
||||
? () => AudioService.seekTo(
|
||||
lyrics.lyrics[i].offset)
|
||||
: null,
|
||||
child: Center(
|
||||
child: Text(
|
||||
lyrics.lyrics[i].text,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 26.0,
|
||||
fontWeight:
|
||||
(_currentIndex == i)
|
||||
? FontWeight.bold
|
||||
: FontWeight.normal),
|
||||
),
|
||||
))));
|
||||
},
|
||||
)),
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
|
|
|
@ -70,22 +70,13 @@ class _PlayerScreenState extends State<PlayerScreen> {
|
|||
systemNavigationBarColor: Color.alphaBlend(
|
||||
palette.dominantColor.color.withOpacity(0.25),
|
||||
Theme.of(context).scaffoldBackgroundColor),
|
||||
systemNavigationBarIconBrightness:
|
||||
ThemeData.estimateBrightnessForColor(
|
||||
palette.dominantColor.color) ==
|
||||
Brightness.light
|
||||
? Brightness.dark
|
||||
: Brightness.light));
|
||||
systemNavigationBarIconBrightness: Brightness.dark));
|
||||
|
||||
//Color gradient
|
||||
if (!settings.blurPlayerBackground) {
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
statusBarColor: palette.dominantColor.color.withOpacity(0.7),
|
||||
statusBarIconBrightness: ThemeData.estimateBrightnessForColor(
|
||||
palette.dominantColor.color.withOpacity(0.7)) ==
|
||||
Brightness.light
|
||||
? Brightness.dark
|
||||
: Brightness.light));
|
||||
statusBarIconBrightness: Brightness.dark));
|
||||
setState(() => _bgGradient = LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
|
|
|
@ -1362,9 +1362,9 @@ class _DirectoryPickerState extends State<DirectoryPicker> {
|
|||
),
|
||||
);
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
...List.generate(snapshot.data.length, (i) {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: List<Widget>.generate(
|
||||
snapshot.data.length, (int i) {
|
||||
StorageInfo si = snapshot.data[i];
|
||||
return ListTile(
|
||||
title: Text(si.rootDir),
|
||||
|
@ -1381,9 +1381,7 @@ class _DirectoryPickerState extends State<DirectoryPicker> {
|
|||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
})
|
||||
],
|
||||
);
|
||||
}));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
92
pubspec.lock
92
pubspec.lock
|
@ -63,14 +63,14 @@ packages:
|
|||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
version: "0.4.6"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.7"
|
||||
version: "2.1.10"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -84,28 +84,28 @@ packages:
|
|||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.1"
|
||||
version: "1.11.5"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.7"
|
||||
version: "6.1.10"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "5.0.0"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
version: "8.0.4"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -140,7 +140,7 @@ packages:
|
|||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "0.3.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -154,7 +154,7 @@ packages:
|
|||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.6.0"
|
||||
version: "3.7.0"
|
||||
collection:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -303,7 +303,7 @@ packages:
|
|||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "1.0.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -324,7 +324,7 @@ packages:
|
|||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
version: "1.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -364,7 +364,7 @@ packages:
|
|||
name: flutter_isolate
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0+14"
|
||||
version: "1.0.0+15"
|
||||
flutter_local_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -435,7 +435,7 @@ packages:
|
|||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.1"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -498,7 +498,7 @@ packages:
|
|||
name: infinite_listview
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1+1"
|
||||
version: "1.1.0"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -512,7 +512,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
version: "0.3.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -561,14 +561,14 @@ packages:
|
|||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.1"
|
||||
marquee:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: marquee
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.1"
|
||||
version: "1.7.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -596,21 +596,7 @@ packages:
|
|||
name: move_to_background
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.0.2"
|
||||
numberpicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -638,7 +624,7 @@ packages:
|
|||
name: open_file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
version: "3.1.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -708,7 +694,7 @@ packages:
|
|||
name: pedantic
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.2"
|
||||
version: "1.11.0"
|
||||
permission_handler:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -757,28 +743,28 @@ packages:
|
|||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.5.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "4.2.1"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
version: "2.0.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.7"
|
||||
version: "0.1.8"
|
||||
quick_actions:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -813,7 +799,7 @@ packages:
|
|||
name: scrobblenaut
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
share:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -834,7 +820,7 @@ packages:
|
|||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4"
|
||||
version: "0.2.4+1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -846,7 +832,7 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+1"
|
||||
version: "0.9.10+3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -874,14 +860,14 @@ packages:
|
|||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.2+3"
|
||||
version: "1.3.2+4"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3+1"
|
||||
version: "1.0.3+3"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -902,7 +888,7 @@ packages:
|
|||
name: stream_transform
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -952,6 +938,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.0"
|
||||
universal_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: universal_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
url_launcher:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1014,7 +1007,7 @@ packages:
|
|||
name: version
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
wakelock:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1042,7 +1035,7 @@ packages:
|
|||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
version: "1.0.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1070,7 +1063,14 @@ packages:
|
|||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "3.1.0"
|
||||
zone_local:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: zone_local
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.22.2"
|
||||
|
|
Loading…
Reference in a new issue