Compare commits
3 Commits
79e7f1841f
...
1fc43fce78
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fc43fce78 | |||
| da1ccb8e3a | |||
| 6e9d945136 |
@@ -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<StatefulWidget> createState() => _CoverImageState();
|
||||
}
|
||||
|
||||
class _CoverImageState extends State<CoverImage> {
|
||||
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),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -43,7 +43,9 @@ class _MusicPlayerState extends State<MusicPlayer> {
|
||||
final List<MusicEntry> _stack = [];
|
||||
int currMusicPos = 0;
|
||||
|
||||
var _showPlaylist = false;
|
||||
var _showPlaylist = true;
|
||||
|
||||
var _playFilteredMusics = false;
|
||||
|
||||
final _filterController = fluent.TextEditingController();
|
||||
MusicsList? _filteredList;
|
||||
@@ -53,8 +55,11 @@ class _MusicPlayerState extends State<MusicPlayer> {
|
||||
|
||||
// Automatically choose next music if required
|
||||
if (currMusicPos >= _stack.length) {
|
||||
var nextId = rng.nextInt(widget.musicsList.length);
|
||||
_stack.add(widget.musicsList[nextId]);
|
||||
var list = _playFilteredMusics
|
||||
? _filteredList ?? widget.musicsList
|
||||
: widget.musicsList;
|
||||
var nextId = rng.nextInt(list.length);
|
||||
_stack.add(list[nextId]);
|
||||
}
|
||||
|
||||
return _stack[currMusicPos];
|
||||
@@ -235,11 +240,7 @@ class _MusicPlayerState extends State<MusicPlayer> {
|
||||
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 +344,17 @@ class _MusicPlayerState extends State<MusicPlayer> {
|
||||
itemBuilder: (c, i) {
|
||||
final music = (_filteredList ?? widget.musicsList)[i];
|
||||
return ListTile(
|
||||
leading: RoundedImage(
|
||||
child: CoverImage(
|
||||
delayLoading: const Duration(seconds: 2),
|
||||
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,
|
||||
@@ -352,6 +364,13 @@ class _MusicPlayerState extends State<MusicPlayer> {
|
||||
itemCount: (_filteredList ?? widget.musicsList).length,
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: fluent.ToggleSwitch(
|
||||
checked: _playFilteredMusics,
|
||||
onChanged: (v) => setState(() => _playFilteredMusics = v),
|
||||
),
|
||||
title: const Text("Play only filtered musics"),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -379,3 +398,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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
99
pubspec.lock
99
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:
|
||||
@@ -35,35 +35,28 @@ packages:
|
||||
name: cached_network_image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
version: "3.2.2"
|
||||
cached_network_image_platform_interface:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cached_network_image_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "2.0.0"
|
||||
cached_network_image_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cached_network_image_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
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,35 +112,35 @@ packages:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
version: "6.1.4"
|
||||
fluent_ui:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluent_ui
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.12.0"
|
||||
version: "4.0.1"
|
||||
fluentui_system_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: fluentui_system_icons
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.170"
|
||||
version: "1.1.182"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@@ -173,7 +166,7 @@ packages:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.1"
|
||||
flutter_localizations:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -202,7 +195,7 @@ packages:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.4"
|
||||
version: "0.13.5"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -230,28 +223,28 @@ packages:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "2.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
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,28 +258,28 @@ packages:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
version: "1.8.2"
|
||||
path_provider:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.10"
|
||||
version: "2.0.11"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.14"
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.9"
|
||||
version: "2.0.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -307,14 +300,14 @@ packages:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
version: "2.0.5"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -335,7 +328,7 @@ packages:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
version: "2.1.3"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -349,14 +342,14 @@ packages:
|
||||
name: recase
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
version: "4.1.0"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: rxdart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.27.4"
|
||||
version: "0.27.5"
|
||||
scroll_pos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -375,21 +368,21 @@ packages:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
version: "1.9.0"
|
||||
sqflite:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2+1"
|
||||
version: "2.1.0"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.1+1"
|
||||
version: "2.3.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -410,28 +403,28 @@ packages:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0+2"
|
||||
version: "3.0.0+3"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
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:
|
||||
@@ -445,14 +438,14 @@ packages:
|
||||
name: url_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
version: "6.1.6"
|
||||
url_launcher_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.0.17"
|
||||
version: "6.0.19"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -480,14 +473,14 @@ packages:
|
||||
name: url_launcher_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "2.1.1"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
version: "2.0.13"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -515,49 +508,49 @@ packages:
|
||||
name: video_player
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.7"
|
||||
video_player_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.5"
|
||||
version: "2.3.9"
|
||||
video_player_avfoundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_avfoundation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.4"
|
||||
version: "2.3.6"
|
||||
video_player_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.1.2"
|
||||
version: "5.1.4"
|
||||
video_player_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: video_player_web
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.10"
|
||||
version: "2.0.12"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
version: "3.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0+1"
|
||||
version: "0.2.0+2"
|
||||
sdks:
|
||||
dart: ">=2.17.0 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
dart: ">=2.18.0 <3.0.0"
|
||||
flutter: ">=3.3.0"
|
||||
|
||||
@@ -39,12 +39,12 @@ dependencies:
|
||||
dio: ^4.0.4
|
||||
|
||||
# Fluent ui
|
||||
fluent_ui: ^3.9.1
|
||||
fluent_ui: ^4.0.1
|
||||
fluentui_system_icons: ^1.1.162
|
||||
|
||||
# Image processing
|
||||
cached_network_image: ^3.2.1
|
||||
cached_network_image_platform_interface: ^1.0.0
|
||||
cached_network_image: ^3.2.2
|
||||
cached_network_image_platform_interface: ^2.0.0
|
||||
|
||||
# Audio player
|
||||
video_player: ^2.3.0
|
||||
@@ -65,7 +65,7 @@ dev_dependencies:
|
||||
# activated in the `analysis_options.yaml` file located at the root of your
|
||||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
flutter_lints: ^1.0.0
|
||||
flutter_lints: ^2.0.1
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
Reference in New Issue
Block a user