diff --git a/lib/api/player.dart b/lib/api/player.dart index 6f4ef4f..6c73d26 100644 --- a/lib/api/player.dart +++ b/lib/api/player.dart @@ -29,7 +29,7 @@ class PlayerHelper { QueueSource queueSource; LoopMode repeatType = LoopMode.off; //Find queue index by id - int get queueIndex => AudioService.queue.indexWhere((mi) => mi.id == AudioService.currentMediaItem?.id??'Random string so it returns -1'); + int get queueIndex => AudioService.queue == null ? 0 : AudioService.queue.indexWhere((mi) => mi.id == AudioService.currentMediaItem?.id??'Random string so it returns -1'); Future start() async { //Subscribe to custom events diff --git a/lib/ui/cached_image.dart b/lib/ui/cached_image.dart index 20571a2..b48ba49 100644 --- a/lib/ui/cached_image.dart +++ b/lib/ui/cached_image.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:palette_generator/palette_generator.dart'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:photo_view/photo_view.dart'; ImagesDatabase imagesDatabase = ImagesDatabase(); @@ -78,3 +79,61 @@ class _CachedImageState extends State { ); } } + +class ZoomableImage extends StatefulWidget { + final String url; + final bool rounded; + final double width; + + ZoomableImage({@required this.url, this.rounded = false, this.width}); + + @override + _ZoomableImageState createState() => _ZoomableImageState(); +} + +class _ZoomableImageState extends State { + BuildContext ctx; + PhotoViewController controller; + bool photoViewOpened = false; + + @override + void initState() { + super.initState(); + controller = PhotoViewController() + ..outputStateStream.listen(listener); + } + + // Listener of PhotoView scale changes. Used for closing PhotoView by pinch-in + void listener(PhotoViewControllerValue value) { + if (value.scale < 0.16 && photoViewOpened) { + Navigator.pop(ctx); + photoViewOpened = false; // to avoid multiple pop() when picture are being scaled out too slowly + } + } + + @override + Widget build(BuildContext context) { + ctx = context; + return FlatButton( + child: CachedImage( + url: widget.url, + rounded: widget.rounded, + width: widget.width, + fullThumb: true, + ), + onPressed: () { + Navigator.of(context).push(PageRouteBuilder( + opaque: false, // transparent background + pageBuilder: (context, a, b) { + photoViewOpened = true; + return PhotoView( + imageProvider: CachedNetworkImageProvider(widget.url), + maxScale: 8.0, + minScale: 0.2, + controller: controller, + backgroundDecoration: + BoxDecoration(color: Color.fromARGB(0x90, 0, 0, 0))); + })); + }); + } +} \ No newline at end of file diff --git a/lib/ui/details_screens.dart b/lib/ui/details_screens.dart index 3de835d..4748515 100644 --- a/lib/ui/details_screens.dart +++ b/lib/ui/details_screens.dart @@ -60,10 +60,9 @@ class AlbumDetails extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Container(height: 8.0,), - CachedImage( + ZoomableImage( url: album.art.full, width: MediaQuery.of(context).size.width / 2, - fullThumb: true, rounded: true, ), Container(height: 8,), @@ -303,11 +302,10 @@ class ArtistDetails extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - CachedImage( + ZoomableImage( url: artist.picture.full, width: MediaQuery.of(context).size.width / 2 - 8, rounded: true, - fullThumb: true, ), Container( width: MediaQuery.of(context).size.width / 2 - 8, diff --git a/lib/ui/player_screen.dart b/lib/ui/player_screen.dart index e6ecd8e..eb3feed 100644 --- a/lib/ui/player_screen.dart +++ b/lib/ui/player_screen.dart @@ -470,10 +470,7 @@ class _BigAlbumArtState extends State { if (_animationLock) return; AudioService.skipToQueueItem(AudioService.queue[index].id); }, - children: List.generate(AudioService.queue.length, (i) => CachedImage( - url: AudioService.queue[i].artUri, - fullThumb: true, - )), + children: List.generate(AudioService.queue.length, (i) => ZoomableImage(url: AudioService.queue[i].artUri)), ), ); } diff --git a/pubspec.lock b/pubspec.lock index 4fd6485..bdfe5b6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -651,6 +651,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + photo_view: + dependency: "direct main" + description: + name: photo_view + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.2" platform: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a3794fc..e6a6ad5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -69,6 +69,7 @@ dependencies: share: ^0.6.5+2 numberpicker: ^1.2.1 quick_actions: ^0.4.0+10 + photo_view: audio_session: ^0.0.9 audio_service: