diff --git a/lib/ui/cover_image.dart b/lib/ui/cover_image.dart index 9513013..304e8b2 100644 --- a/lib/ui/cover_image.dart +++ b/lib/ui/cover_image.dart @@ -1,16 +1,19 @@ +import 'dart:async'; + import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart'; import 'package:flutter/material.dart'; import 'package:music_web_player/api.dart'; import 'package:music_web_player/config.dart'; -class CoverImage extends StatelessWidget { +class CoverImage extends StatefulWidget { final MusicEntry music; final double? width; final double? height; final BoxFit? fit; final Icon? icon; final Color? backgroundColor; + final Duration? delayLoading; const CoverImage({ Key? key, @@ -20,31 +23,61 @@ class CoverImage extends StatelessWidget { this.icon, this.fit, this.backgroundColor, + this.delayLoading, }) : super(key: key); + @override + State createState() => _CoverImageState(); +} + +class _CoverImageState extends State { + var _canShowImage = true; + Timer? _timer; + + @override + void initState() { + super.initState(); + + if (widget.delayLoading != null) { + _canShowImage = false; + Timer(widget.delayLoading!, () { + if (mounted) { + setState(() => _canShowImage = true); + } + }); + } + } + + @override + void dispose() { + super.dispose(); + _timer?.cancel(); + } + @override Widget build(BuildContext context) { + if (!_canShowImage) return _loadingWidget(null); return CachedNetworkImage( - width: width, - height: height, + width: widget.width, + height: widget.height, imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet, - imageUrl: music.coverURL, - cacheKey: music.coverCacheKey, + imageUrl: widget.music.coverURL, + cacheKey: widget.music.coverCacheKey, httpHeaders: {"Token": config.apiToken}, useOldImageOnUrlChange: false, progressIndicatorBuilder: (c, s, p) => _loadingWidget(p.progress), - fit: fit, + fit: widget.fit, errorWidget: (c, s, e) => _loadingWidget(null), ); } Widget _loadingWidget(double? progress) => Container( - color: backgroundColor ?? Colors.black, - width: width, - height: height, + color: widget.backgroundColor ?? Colors.black, + width: widget.width, + height: widget.height, child: Center( child: progress == null - ? icon + ? widget.icon : CircularProgressIndicator(value: progress), ), ); diff --git a/lib/ui/music_player.dart b/lib/ui/music_player.dart index 8a0c397..b810c84 100644 --- a/lib/ui/music_player.dart +++ b/lib/ui/music_player.dart @@ -235,11 +235,7 @@ class _MusicPlayerState extends State { mainAxisAlignment: fluent.MainAxisAlignment.center, crossAxisAlignment: fluent.CrossAxisAlignment.center, children: [ - Material( - borderRadius: const BorderRadius.all( - Radius.circular(18.0), - ), - clipBehavior: Clip.hardEdge, + RoundedImage( child: CoverImage( width: 250, height: 250, @@ -343,6 +339,17 @@ class _MusicPlayerState extends State { itemBuilder: (c, i) { final music = (_filteredList ?? widget.musicsList)[i]; return ListTile( + leading: RoundedImage( + child: CoverImage( + delayLoading: const Duration(seconds: 3), + music: music, + width: 50, + height: 50, + fit: BoxFit.cover, + backgroundColor: Colors.transparent, + icon: const Icon(Icons.music_note), + ), + ), title: Text(music.title), subtitle: Text(music.artist), selected: currMusic == music, @@ -379,3 +386,20 @@ class DurationText extends StatelessWidget { ); } } + +class RoundedImage extends StatelessWidget { + final Widget child; + + const RoundedImage({Key? key, required this.child}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Material( + borderRadius: const BorderRadius.all( + Radius.circular(18.0), + ), + clipBehavior: Clip.hardEdge, + child: child, + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 62e281b..6fc6e4f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" audio_service_platform_interface: dependency: transitive description: @@ -56,14 +56,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" chewie_audio: dependency: "direct main" description: @@ -77,7 +70,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: @@ -119,7 +112,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: transitive description: @@ -237,21 +230,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" octo_image: dependency: transitive description: @@ -265,7 +258,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_provider: dependency: transitive description: @@ -375,7 +368,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" sqflite: dependency: transitive description: @@ -410,7 +403,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" synchronized: dependency: transitive description: @@ -424,14 +417,14 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" typed_data: dependency: transitive description: