修复bug
This commit is contained in:
parent
db53f60925
commit
21030681a2
@ -44,7 +44,16 @@ class CreatePlaylistDialog extends Dialog {
|
|||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 19.h),
|
SizedBox(height: 4.h),
|
||||||
|
Text(
|
||||||
|
'Enter up to 60 characters',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 12.sp,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
Container(
|
Container(
|
||||||
height: 30.h,
|
height: 30.h,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
@ -64,7 +73,7 @@ class CreatePlaylistDialog extends Dialog {
|
|||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
style: TextStyle(color: Colors.white, fontSize: 15.sp),
|
style: TextStyle(color: Colors.white, fontSize: 15.sp),
|
||||||
textAlignVertical: TextAlignVertical.center,
|
textAlignVertical: TextAlignVertical.center,
|
||||||
maxLength: 30,
|
maxLength: 60,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
counterText: '',
|
counterText: '',
|
||||||
hintText: 'My playlist1',
|
hintText: 'My playlist1',
|
||||||
@ -78,7 +87,7 @@ class CreatePlaylistDialog extends Dialog {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 19.h),
|
SizedBox(height: 16.h),
|
||||||
DividerWidget(
|
DividerWidget(
|
||||||
height: 0.5.h,
|
height: 0.5.h,
|
||||||
color: const Color(0xA6545458),
|
color: const Color(0xA6545458),
|
||||||
@ -114,11 +123,9 @@ class CreatePlaylistDialog extends Dialog {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
if (isConfirm) {
|
if (isConfirm) {
|
||||||
if (ObjUtil.isNotEmpty(_textEditingController.text)) {
|
if (ObjUtil.isNotEmpty(_textEditingController.text)) {
|
||||||
|
Get.back();
|
||||||
onTap(_textEditingController.text);
|
onTap(_textEditingController.text);
|
||||||
} else {
|
|
||||||
onTap('My playlist1');
|
|
||||||
}
|
}
|
||||||
Get.back();
|
|
||||||
} else {
|
} else {
|
||||||
Get.back();
|
Get.back();
|
||||||
}
|
}
|
||||||
|
|||||||
2
lib/data/cache/music_cache_manager.dart
vendored
2
lib/data/cache/music_cache_manager.dart
vendored
@ -10,7 +10,7 @@ class MusicCacheManager {
|
|||||||
Config(
|
Config(
|
||||||
key,
|
key,
|
||||||
stalePeriod: const Duration(days: 7),
|
stalePeriod: const Duration(days: 7),
|
||||||
maxNrOfCacheObjects: 20,
|
maxNrOfCacheObjects: 30,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -158,7 +158,7 @@ class MusicBox {
|
|||||||
Future<void> putSearchHistory(String history) async {
|
Future<void> putSearchHistory(String history) async {
|
||||||
var historyList = getAllSearchHistory();
|
var historyList = getAllSearchHistory();
|
||||||
if (!historyList.contains(history)) {
|
if (!historyList.contains(history)) {
|
||||||
if (historyList.length >= 9) {
|
if (historyList.length >= 10) {
|
||||||
historyList.removeLast();
|
historyList.removeLast();
|
||||||
}
|
}
|
||||||
historyList.insert(0, history);
|
historyList.insert(0, history);
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:tone_snap/ads/app_open_ad_manager.dart';
|
import 'package:tone_snap/ads/app_open_ad_manager.dart';
|
||||||
@ -14,7 +12,6 @@ import 'package:tone_snap/global/app_config.dart';
|
|||||||
import 'package:tone_snap/global/app_lifecycle_reactor.dart';
|
import 'package:tone_snap/global/app_lifecycle_reactor.dart';
|
||||||
import 'package:tone_snap/global/network_connectivity_service.dart';
|
import 'package:tone_snap/global/network_connectivity_service.dart';
|
||||||
import 'package:tone_snap/modules/sideb/controllers/main_controller.dart';
|
import 'package:tone_snap/modules/sideb/controllers/main_controller.dart';
|
||||||
import 'package:tone_snap/res/themes/app_themes.dart';
|
|
||||||
import 'package:tone_snap/routes/app_routes.dart';
|
import 'package:tone_snap/routes/app_routes.dart';
|
||||||
import 'package:tone_snap/utils/log_util.dart';
|
import 'package:tone_snap/utils/log_util.dart';
|
||||||
|
|
||||||
|
|||||||
@ -137,11 +137,17 @@ class AlbumSongListController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 点击播放全部歌曲
|
/// 点击播放全部歌曲
|
||||||
Future<void> onTapPlayAll() async {
|
Future<void> onTapPlayAll(int type) async {
|
||||||
if (musicList.isNotEmpty) {
|
if (musicList.isNotEmpty) {
|
||||||
final randomNumber = NumUtil.getRandomNumber(0, musicList.length);
|
int index = 0;
|
||||||
List<MusicModel> playList = await _next(musicList[randomNumber].value.videoId, playlistId: musicList[randomNumber].value.playlistId);
|
if (type == 1) {
|
||||||
musicPlayerController.playMusic(playList[randomNumber].videoId, playList: playList);
|
if (musicPlayerController.getMusicModel() != null) {
|
||||||
|
int currentIndex = musicList.indexWhere((e) => e.value.videoId == musicPlayerController.getMusicModel()!.value.videoId);
|
||||||
|
index = NumUtil.getRandomNumberExcludingCurrent(0, musicList.length, currentIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<MusicModel> playList = await _next(musicList[index].value.videoId, playlistId: musicList[index].value.playlistId);
|
||||||
|
musicPlayerController.playMusic(playList[index].videoId, playList: playList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,25 +22,25 @@ class AlbumSongListView extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: const Color(0xFF121212),
|
backgroundColor: const Color(0xFF121212),
|
||||||
body: Stack(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildPageBgImg(),
|
SizedBox(
|
||||||
Column(
|
height: 413.h,
|
||||||
children: [
|
child: Stack(
|
||||||
SizedBox(
|
children: [
|
||||||
height: 413.h,
|
_buildPageBgImg(),
|
||||||
child: Column(
|
Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
const MusicAppbar(),
|
const MusicAppbar(),
|
||||||
_buildIntroduction(),
|
_buildPlaylistInfo(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
_buildList(),
|
),
|
||||||
const RemovePaddingMusicBar(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
|
_buildList(),
|
||||||
|
const RemovePaddingMusicBar(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -52,126 +52,125 @@ class AlbumSongListView extends StatelessWidget {
|
|||||||
return NetworkImageWidget(
|
return NetworkImageWidget(
|
||||||
url: controller.coverUrl.value,
|
url: controller.coverUrl.value,
|
||||||
width: 1.sw,
|
width: 1.sw,
|
||||||
height: 413.h,
|
height: double.infinity,
|
||||||
|
fit: BoxFit.cover,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildIntroduction() {
|
Widget _buildPlaylistInfo() {
|
||||||
return SizedBox(
|
return ClipRect(
|
||||||
height: 173.h,
|
child: BackdropFilter(
|
||||||
child: Stack(
|
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
|
||||||
children: [
|
child: Container(
|
||||||
ClipRect(
|
height: 173.h,
|
||||||
child: BackdropFilter(
|
padding: EdgeInsets.symmetric(horizontal: 18.w, vertical: 18.h),
|
||||||
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
|
decoration: BoxDecoration(
|
||||||
child: ClipRRect(
|
borderRadius: BorderRadius.only(topLeft: Radius.circular(16.r), topRight: Radius.circular(16.r)),
|
||||||
borderRadius: BorderRadius.only(topLeft: Radius.circular(16.r), topRight: Radius.circular(16.r)),
|
image: const DecorationImage(
|
||||||
child: Image.asset(
|
image: AssetImage(
|
||||||
Assets.sideBPlaylistTitleBg,
|
Assets.sideBPlaylistTitleBg,
|
||||||
width: 1.sw,
|
|
||||||
height: double.infinity,
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
child: Column(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 18).w,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
Obx(() {
|
||||||
children: [
|
return Text(
|
||||||
SizedBox(height: 18.h),
|
ObjUtil.getStr(controller.title.value),
|
||||||
Obx(() {
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 22.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
SizedBox(height: 10.h),
|
||||||
|
Expanded(
|
||||||
|
child: Obx(() {
|
||||||
return Text(
|
return Text(
|
||||||
ObjUtil.getStr(controller.title.value),
|
ObjUtil.getStr(controller.description.value),
|
||||||
maxLines: 1,
|
maxLines: 3,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: const Color(0x99FFFFFF),
|
||||||
fontSize: 22.sp,
|
fontSize: 12.sp,
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
SizedBox(height: 10.h),
|
),
|
||||||
Expanded(
|
SizedBox(height: 10.h),
|
||||||
child: Obx(() {
|
Row(
|
||||||
return Text(
|
children: [
|
||||||
ObjUtil.getStr(controller.description.value),
|
_buildPlayAll(Assets.sideBPlaylistPlayAll, 'Play all', 0),
|
||||||
maxLines: 3,
|
SizedBox(width: 10.w),
|
||||||
overflow: TextOverflow.ellipsis,
|
_buildPlayAll(Assets.sideBPlaylistPlayAllRandom, 'Shuffle Playback', 1),
|
||||||
style: TextStyle(
|
const Spacer(),
|
||||||
color: const Color(0x99FFFFFF),
|
ClipOval(
|
||||||
fontSize: 12.sp,
|
child: Material(
|
||||||
),
|
color: Colors.transparent,
|
||||||
);
|
child: InkWell(
|
||||||
}),
|
onTap: controller.onTapCollect,
|
||||||
),
|
child: Padding(
|
||||||
SizedBox(height: 10.h),
|
padding: const EdgeInsets.all(6).w,
|
||||||
Row(
|
child: Obx(() {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
return Image.asset(
|
||||||
children: [
|
controller.isCollect.value ? Assets.sideBCollected : Assets.sideBNotCollectionAlbum,
|
||||||
GestureDetector(
|
|
||||||
onTap: controller.onTapPlayAll,
|
|
||||||
child: Container(
|
|
||||||
width: 138.w,
|
|
||||||
height: 32.h,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4).w,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(16).r,
|
|
||||||
color: const Color(0x1A80F988),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Image.asset(
|
|
||||||
Assets.sideBPlaylistPlayAllRandom,
|
|
||||||
width: 24.w,
|
width: 24.w,
|
||||||
height: 24.w,
|
height: 24.w,
|
||||||
),
|
);
|
||||||
SizedBox(width: 4.w),
|
}),
|
||||||
Expanded(
|
|
||||||
child: Obx(() {
|
|
||||||
return Text(
|
|
||||||
'Play all (${controller.musicList.length})',
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ClipOval(
|
),
|
||||||
child: Material(
|
],
|
||||||
color: Colors.transparent,
|
),
|
||||||
child: InkWell(
|
],
|
||||||
onTap: controller.onTapCollect,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(6).w,
|
|
||||||
child: Obx(() {
|
|
||||||
return Image.asset(
|
|
||||||
controller.isCollect.value ? Assets.sideBCollected : Assets.sideBNotCollectionAlbum,
|
|
||||||
width: 24.w,
|
|
||||||
height: 24.w,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(height: 18.h),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPlayAll(String img, String label, int type) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => controller.onTapPlayAll(type),
|
||||||
|
child: Container(
|
||||||
|
width: 100.w,
|
||||||
|
height: 32.h,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 4).w,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(16).r,
|
||||||
|
color: const Color(0x1A80F988),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
img,
|
||||||
|
width: 24.w,
|
||||||
|
height: 24.w,
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
Expanded(
|
||||||
|
child: Obx(() {
|
||||||
|
return Text(
|
||||||
|
'$label (${controller.musicList.length})',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
// Description: 音乐播放器控制器
|
// Description: 音乐播放器控制器
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@ -104,9 +105,13 @@ class MusicPlayerController extends GetxController {
|
|||||||
Get.currentRoute == AppRoutes.playPage ? MusicBar().hide() : MusicBar().show();
|
Get.currentRoute == AppRoutes.playPage ? MusicBar().hide() : MusicBar().show();
|
||||||
try {
|
try {
|
||||||
MusicModel? model = OfflineBox().getList().firstWhereOrNull((e) => e.videoId == getMusicModel()!.value.videoId!);
|
MusicModel? model = OfflineBox().getList().firstWhereOrNull((e) => e.videoId == getMusicModel()!.value.videoId!);
|
||||||
if (model != null) {
|
if (model != null && ObjUtil.isNotEmpty(model.localPath)) {
|
||||||
// 有下载
|
// 有下载
|
||||||
LogUtil.d('读取下载路径=${model.localPath}');
|
LogUtil.d('读取下载路径=${model.localPath}');
|
||||||
|
if (!await File(model.localPath!).exists()) {
|
||||||
|
BaseEasyLoading.toast('file does not exist');
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _player.setFilePath(model.localPath!);
|
await _player.setFilePath(model.localPath!);
|
||||||
} else {
|
} else {
|
||||||
// 无下载
|
// 无下载
|
||||||
@ -192,7 +197,7 @@ class MusicPlayerController extends GetxController {
|
|||||||
if (!_isCompletedHandled) {
|
if (!_isCompletedHandled) {
|
||||||
_isCompletedHandled = true;
|
_isCompletedHandled = true;
|
||||||
_player.seek(Duration.zero);
|
_player.seek(Duration.zero);
|
||||||
nextTrack();
|
nextTrack(manualSwitch: false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -217,7 +222,7 @@ class MusicPlayerController extends GetxController {
|
|||||||
|
|
||||||
/// 开始/结束拖动进度条
|
/// 开始/结束拖动进度条
|
||||||
Future<void> seekStartEnd(int value) async {
|
Future<void> seekStartEnd(int value) async {
|
||||||
if (processingState.value == ProcessingState.ready) {
|
if (processingState.value == ProcessingState.buffering || processingState.value == ProcessingState.ready) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
_seekFrontPlaying = _player.playing;
|
_seekFrontPlaying = _player.playing;
|
||||||
if (_player.playing) {
|
if (_player.playing) {
|
||||||
@ -271,13 +276,15 @@ class MusicPlayerController extends GetxController {
|
|||||||
_startPlay();
|
_startPlay();
|
||||||
break;
|
break;
|
||||||
case PlayMode.singleCycle:
|
case PlayMode.singleCycle:
|
||||||
|
currentIndex.value = (currentIndex.value - 1 + playlist.length) % playlist.length;
|
||||||
|
_startPlay();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 下一首
|
/// 下一首
|
||||||
Future<void> nextTrack() async {
|
Future<void> nextTrack({bool manualSwitch = true}) async {
|
||||||
if (playlist.length > 1) {
|
if (playlist.length > 1) {
|
||||||
switch(playMode.value) {
|
switch(playMode.value) {
|
||||||
case PlayMode.listLoop:
|
case PlayMode.listLoop:
|
||||||
@ -291,6 +298,10 @@ class MusicPlayerController extends GetxController {
|
|||||||
_startPlay();
|
_startPlay();
|
||||||
break;
|
break;
|
||||||
case PlayMode.singleCycle:
|
case PlayMode.singleCycle:
|
||||||
|
if (manualSwitch) {
|
||||||
|
currentIndex.value = (currentIndex.value + 1) % playlist.length;
|
||||||
|
_startPlay();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,21 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tone_snap/components/view_state_widget.dart';
|
||||||
import 'package:tone_snap/data/models/music_model.dart';
|
import 'package:tone_snap/data/models/music_model.dart';
|
||||||
import 'package:tone_snap/data/models/playlist_model.dart';
|
import 'package:tone_snap/data/models/playlist_model.dart';
|
||||||
import 'package:tone_snap/data/storage/playlists_box.dart';
|
import 'package:tone_snap/data/storage/playlists_box.dart';
|
||||||
import 'package:tone_snap/modules/sideb/initial/initial_controller.dart';
|
import 'package:tone_snap/modules/sideb/controllers/music_player_controller.dart';
|
||||||
import 'package:tone_snap/modules/sideb/more_playlist_bottom_sheet/more_playlist_bottom_sheet_view.dart';
|
import 'package:tone_snap/modules/sideb/more_playlist_bottom_sheet/more_playlist_bottom_sheet_view.dart';
|
||||||
import 'package:tone_snap/routes/app_routes.dart';
|
import 'package:tone_snap/routes/app_routes.dart';
|
||||||
|
import 'package:tone_snap/utils/num_util.dart';
|
||||||
import 'package:tone_snap/utils/obj_util.dart';
|
import 'package:tone_snap/utils/obj_util.dart';
|
||||||
|
|
||||||
class CustomPlaylistController extends GetxController {
|
class CustomPlaylistController extends GetxController {
|
||||||
static CustomPlaylistController get to => Get.find<CustomPlaylistController>();
|
static CustomPlaylistController get to => Get.find<CustomPlaylistController>();
|
||||||
|
var musicPlayerController = MusicPlayerController.to;
|
||||||
late String playlistModelId;
|
late String playlistModelId;
|
||||||
var playlistModel = Rx<PlaylistModel?>(null);
|
var playlistModel = Rx<PlaylistModel?>(null);
|
||||||
|
var viewState = ViewState.normal.obs;
|
||||||
var musicList = <Rx<MusicModel>>[].obs;
|
var musicList = <Rx<MusicModel>>[].obs;
|
||||||
var showSearch = false.obs;
|
var showSearch = false.obs;
|
||||||
var textEditingController = TextEditingController();
|
var textEditingController = TextEditingController();
|
||||||
@ -31,12 +35,15 @@ class CustomPlaylistController extends GetxController {
|
|||||||
|
|
||||||
void getPlaylistMode() {
|
void getPlaylistMode() {
|
||||||
playlistModel.value = PlaylistsBox().getPlaylistModel(playlistModelId);
|
playlistModel.value = PlaylistsBox().getPlaylistModel(playlistModelId);
|
||||||
playlistModel.update((fn){});
|
playlistModel.update((fn) {});
|
||||||
_getList();
|
_getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getList() {
|
void _getList() {
|
||||||
musicList.value = playlistModel.value!.musicList!.map((e) => e.obs).toList();
|
if (playlistModel.value != null && playlistModel.value!.musicList != null) {
|
||||||
|
musicList.value = playlistModel.value!.musicList!.map((e) => e.obs).toList();
|
||||||
|
}
|
||||||
|
viewState.value = musicList.isNotEmpty ? ViewState.normal : ViewState.empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getFirstCoverUrl() {
|
String? getFirstCoverUrl() {
|
||||||
@ -54,6 +61,19 @@ class CustomPlaylistController extends GetxController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> onTapPlayAll(int type) async {
|
||||||
|
if (musicList.isNotEmpty) {
|
||||||
|
int index = 0;
|
||||||
|
if (type == 1) {
|
||||||
|
if (musicPlayerController.getMusicModel() != null) {
|
||||||
|
int currentIndex = musicList.indexWhere((e) => e.value.videoId == musicPlayerController.getMusicModel()!.value.videoId);
|
||||||
|
index = NumUtil.getRandomNumberExcludingCurrent(0, musicList.length, currentIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
musicPlayerController.playMusic(musicList[index].value.videoId, playList: musicList.map((e) => e.value).toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onTapShowSearch(bool show) {
|
void onTapShowSearch(bool show) {
|
||||||
if (show && musicList.isEmpty) {
|
if (show && musicList.isEmpty) {
|
||||||
return;
|
return;
|
||||||
@ -85,9 +105,4 @@ class CustomPlaylistController extends GetxController {
|
|||||||
'playList': musicList.map((e) => e.value).toList(),
|
'playList': musicList.map((e) => e.value).toList(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTapAddSongs() {
|
|
||||||
Get.until((route) => route.isFirst);
|
|
||||||
InitialController.to.onBottomAppBarItemChanged(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,9 +6,11 @@ import 'package:get/get.dart';
|
|||||||
import 'package:tone_snap/components/base_scrollbar.dart';
|
import 'package:tone_snap/components/base_scrollbar.dart';
|
||||||
import 'package:tone_snap/components/my_marquee_text.dart';
|
import 'package:tone_snap/components/my_marquee_text.dart';
|
||||||
import 'package:tone_snap/components/network_image_widget.dart';
|
import 'package:tone_snap/components/network_image_widget.dart';
|
||||||
|
import 'package:tone_snap/components/view_state_widget.dart';
|
||||||
import 'package:tone_snap/generated/assets.dart';
|
import 'package:tone_snap/generated/assets.dart';
|
||||||
import 'package:tone_snap/modules/sideb/widgets/music_appbar.dart';
|
import 'package:tone_snap/modules/sideb/widgets/music_appbar.dart';
|
||||||
import 'package:tone_snap/modules/sideb/widgets/music_item.dart';
|
import 'package:tone_snap/modules/sideb/widgets/music_item.dart';
|
||||||
|
import 'package:tone_snap/modules/sideb/widgets/remove_padding_music_bar.dart';
|
||||||
import 'package:tone_snap/res/themes/app_colors.dart';
|
import 'package:tone_snap/res/themes/app_colors.dart';
|
||||||
import 'package:tone_snap/utils/date_util.dart';
|
import 'package:tone_snap/utils/date_util.dart';
|
||||||
import 'package:tone_snap/utils/obj_util.dart';
|
import 'package:tone_snap/utils/obj_util.dart';
|
||||||
@ -28,6 +30,7 @@ class CustomPlaylistView extends StatelessWidget {
|
|||||||
_buildPlaylistInfo(),
|
_buildPlaylistInfo(),
|
||||||
_buildPlayAllSearch(),
|
_buildPlayAllSearch(),
|
||||||
_buildList(),
|
_buildList(),
|
||||||
|
const RemovePaddingMusicBar(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -135,25 +138,9 @@ class CustomPlaylistView extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
_buildPlayAll(Assets.sideBPlaylistPlayAll, 'Play all', 0),
|
||||||
Assets.sideBPlaylistPlayAll,
|
SizedBox(width: 10.w),
|
||||||
width: 24.w,
|
_buildPlayAll(Assets.sideBPlaylistPlayAllRandom, 'Shuffle Playback', 1),
|
||||||
height: 24.w,
|
|
||||||
),
|
|
||||||
SizedBox(width: 6.w),
|
|
||||||
Expanded(
|
|
||||||
child: Obx(() {
|
|
||||||
return Text(
|
|
||||||
'Play all (${controller.musicList.length})',
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 14.sp,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -228,63 +215,100 @@ class CustomPlaylistView extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildList() {
|
Widget _buildPlayAll(String img, String label, int type) {
|
||||||
return Expanded(
|
return GestureDetector(
|
||||||
child: BaseScrollbar(
|
onTap: () => controller.onTapPlayAll(type),
|
||||||
child: Obx(() {
|
child: Container(
|
||||||
return Visibility(
|
width: 100.w,
|
||||||
visible: controller.musicList.isNotEmpty,
|
height: 32.h,
|
||||||
replacement: _buildEmpty(),
|
padding: const EdgeInsets.symmetric(horizontal: 4).w,
|
||||||
child: ListView.builder(
|
child: Row(
|
||||||
itemCount: controller.musicList.length,
|
children: [
|
||||||
itemBuilder: (context, index) {
|
Image.asset(
|
||||||
return MusicItem(
|
img,
|
||||||
musicModel: controller.musicList[index],
|
width: 24.w,
|
||||||
playlistModelId: controller.playlistModel.value!.id,
|
height: 24.w,
|
||||||
onTapItem: () => controller.onTapItem(controller.musicList[index].value),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
SizedBox(width: 4.w),
|
||||||
}),
|
Expanded(
|
||||||
|
child: Obx(() {
|
||||||
|
return Text(
|
||||||
|
'$label (${controller.musicList.length})',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 14.sp,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEmpty() {
|
Widget _buildList() {
|
||||||
return Column(
|
return Expanded(
|
||||||
children: [
|
child: Obx(() {
|
||||||
SizedBox(height: 40.h),
|
return ViewStateWidget(
|
||||||
Text(
|
viewState: controller.viewState.value,
|
||||||
'Nothing Yet',
|
child: BaseScrollbar(
|
||||||
style: TextStyle(
|
child: Obx(() {
|
||||||
color: const Color(0x99FFFFFF),
|
return Visibility(
|
||||||
fontSize: 14.sp,
|
child: ListView.builder(
|
||||||
|
itemCount: controller.musicList.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return MusicItem(
|
||||||
|
musicModel: controller.musicList[index],
|
||||||
|
playlistModelId: controller.playlistModel.value!.id,
|
||||||
|
onTapItem: () => controller.onTapItem(controller.musicList[index].value),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
SizedBox(height: 16.h),
|
}),
|
||||||
GestureDetector(
|
|
||||||
onTap: controller.onTapAddSongs,
|
|
||||||
child: Container(
|
|
||||||
width: 122.w,
|
|
||||||
height: 35.h,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(40).r,
|
|
||||||
border: Border.all(
|
|
||||||
color: seedColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
'Add Songs',
|
|
||||||
style: TextStyle(
|
|
||||||
color: seedColor,
|
|
||||||
fontSize: 16.sp,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Widget _buildEmpty() {
|
||||||
|
// return Column(
|
||||||
|
// children: [
|
||||||
|
// SizedBox(height: 40.h),
|
||||||
|
// Text(
|
||||||
|
// 'Nothing Yet',
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: const Color(0x99FFFFFF),
|
||||||
|
// fontSize: 14.sp,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: 16.h),
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: controller.onTapAddSongs,
|
||||||
|
// child: Container(
|
||||||
|
// width: 122.w,
|
||||||
|
// height: 35.h,
|
||||||
|
// alignment: Alignment.center,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// borderRadius: BorderRadius.circular(40).r,
|
||||||
|
// border: Border.all(
|
||||||
|
// color: seedColor,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Text(
|
||||||
|
// 'Add Songs',
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: seedColor,
|
||||||
|
// fontSize: 16.sp,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,7 @@ class MoreBottomSheetController extends GetxController {
|
|||||||
RemindDialog(
|
RemindDialog(
|
||||||
content: 'Confirm to remove this song?',
|
content: 'Confirm to remove this song?',
|
||||||
confirmOnTap: () async {
|
confirmOnTap: () async {
|
||||||
|
Get.back();
|
||||||
await OfflineBox().delete(musicModel.value.videoId!);
|
await OfflineBox().delete(musicModel.value.videoId!);
|
||||||
musicModel.update((fn) => fn?.taskStatus = null);
|
musicModel.update((fn) => fn?.taskStatus = null);
|
||||||
BaseEasyLoading.toast('Removed');
|
BaseEasyLoading.toast('Removed');
|
||||||
|
|||||||
@ -94,6 +94,9 @@ class PlayPageController extends GetxController {
|
|||||||
await LoveSongsBox().add(musicPlayerController.getMusicModel()!.value.copyWith());
|
await LoveSongsBox().add(musicPlayerController.getMusicModel()!.value.copyWith());
|
||||||
BaseEasyLoading.toast('Collected');
|
BaseEasyLoading.toast('Collected');
|
||||||
}
|
}
|
||||||
|
if (Get.isRegistered<PersonalMusicLibraryController>()) {
|
||||||
|
PersonalMusicLibraryController.to.refreshLoveSongs();
|
||||||
|
}
|
||||||
musicPlayerController.getMusicModel()!.update((fn) => fn?.isLove = LoveSongsBox().checkLove(musicPlayerController.getMusicModel()!.value.videoId));
|
musicPlayerController.getMusicModel()!.update((fn) => fn?.isLove = LoveSongsBox().checkLove(musicPlayerController.getMusicModel()!.value.videoId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class PlayPageView extends StatelessWidget {
|
|||||||
_buildCover(),
|
_buildCover(),
|
||||||
SizedBox(height: 36.h),
|
SizedBox(height: 36.h),
|
||||||
_buildMusicName(),
|
_buildMusicName(),
|
||||||
SizedBox(height: 24.h),
|
SizedBox(height: 12.h),
|
||||||
_processBar(context),
|
_processBar(context),
|
||||||
SizedBox(height: 24.h),
|
SizedBox(height: 24.h),
|
||||||
],
|
],
|
||||||
@ -61,17 +61,26 @@ class PlayPageView extends StatelessWidget {
|
|||||||
|
|
||||||
/// 页面背景图
|
/// 页面背景图
|
||||||
Widget _buildPageBgImg() {
|
Widget _buildPageBgImg() {
|
||||||
return Obx(() {
|
return ImageFiltered(
|
||||||
return ImageFiltered(
|
imageFilter: ImageFilter.blur(sigmaX: 50.0, sigmaY: 50.0),
|
||||||
imageFilter: ImageFilter.blur(sigmaX: 50.0, sigmaY: 50.0),
|
child: Stack(
|
||||||
child: NetworkImageWidget(
|
children: [
|
||||||
url: musicPlayerController.getMusicModel()?.value.coverUrl,
|
Obx(() {
|
||||||
width: 1.sw,
|
return NetworkImageWidget(
|
||||||
height: 1.sh,
|
url: musicPlayerController.getMusicModel()?.value.coverUrl,
|
||||||
noPlaceholder: true,
|
width: 1.sw,
|
||||||
),
|
height: 1.sh,
|
||||||
);
|
noPlaceholder: true,
|
||||||
});
|
);
|
||||||
|
}),
|
||||||
|
Container(
|
||||||
|
width: 1.sw,
|
||||||
|
height: 1.sh,
|
||||||
|
color: const Color(0xB3000000),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 头部
|
/// 头部
|
||||||
@ -242,31 +251,27 @@ class PlayPageView extends StatelessWidget {
|
|||||||
activeTrackColor: seedColor,
|
activeTrackColor: seedColor,
|
||||||
inactiveTrackColor: const Color(0x4DFFFFFF),
|
inactiveTrackColor: const Color(0x4DFFFFFF),
|
||||||
secondaryActiveTrackColor: seedColor.withOpacity(0.3),
|
secondaryActiveTrackColor: seedColor.withOpacity(0.3),
|
||||||
trackHeight: 3.h,
|
trackHeight: 4.h,
|
||||||
thumbColor: Colors.white,
|
thumbColor: Colors.white,
|
||||||
thumbShape: RoundSliderThumbShape(
|
thumbShape: RoundSliderThumbShape(
|
||||||
disabledThumbRadius: 7.w,
|
disabledThumbRadius: 8.w,
|
||||||
enabledThumbRadius: 7.w,
|
enabledThumbRadius: 8.w,
|
||||||
),
|
),
|
||||||
trackShape: FullWidthTrackShape(),
|
trackShape: FullWidthTrackShape(),
|
||||||
|
overlayShape: RoundSliderOverlayShape(overlayRadius: 10.w), // 扩大覆盖层半径
|
||||||
),
|
),
|
||||||
child: SizedBox(
|
child: Obx(() {
|
||||||
width: 1.sw,
|
return Slider(
|
||||||
height: 7.w,
|
value: musicPlayerController.positionDuration.value.inSeconds.toDouble(),
|
||||||
child: Obx(() {
|
secondaryTrackValue: musicPlayerController.bufferedDuration.value.inSeconds.toDouble(),
|
||||||
return Slider(
|
min: 0,
|
||||||
value: musicPlayerController.positionDuration.value.inSeconds.toDouble(),
|
max: musicPlayerController.totalDuration.value.inSeconds.toDouble(),
|
||||||
secondaryTrackValue: musicPlayerController.bufferedDuration.value.inSeconds.toDouble(),
|
onChanged: (value) => musicPlayerController.seekToPosition(value),
|
||||||
min: 0,
|
onChangeStart: (value) => musicPlayerController.seekStartEnd(0),
|
||||||
max: musicPlayerController.totalDuration.value.inSeconds.toDouble(),
|
onChangeEnd: (value) => musicPlayerController.seekStartEnd(1),
|
||||||
onChanged: (value) => musicPlayerController.seekToPosition(value),
|
);
|
||||||
onChangeStart: (value) => musicPlayerController.seekStartEnd(0),
|
}),
|
||||||
onChangeEnd: (value) => musicPlayerController.seekStartEnd(1),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 8.h),
|
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user