mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 08:08:19 +08:00
committed by
GitHub
parent
84f7f14a29
commit
08a33d9ce5
30
lib/pages/music/video/controller.dart
Normal file
30
lib/pages/music/video/controller.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/music.dart';
|
||||
import 'package:PiliPlus/models_new/music/bgm_detail.dart';
|
||||
import 'package:PiliPlus/models_new/music/bgm_recommend_list.dart';
|
||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MusicRecommendController
|
||||
extends CommonListController<List<BgmRecommend>?, BgmRecommend> {
|
||||
late final String musicId;
|
||||
late final MusicDetail musicDetail;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
final Map<String, dynamic> args = Get.arguments;
|
||||
musicId = args['id'];
|
||||
musicDetail = args['detail'];
|
||||
queryData();
|
||||
}
|
||||
|
||||
@override
|
||||
void checkIsEnd(int length) {
|
||||
isEnd = true;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState<List<BgmRecommend>?>> customGetData() =>
|
||||
MusicHttp.bgmRecommend(musicId);
|
||||
}
|
||||
127
lib/pages/music/video/view.dart
Normal file
127
lib/pages/music/video/view.dart
Normal file
@@ -0,0 +1,127 @@
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/music/bgm_recommend_list.dart';
|
||||
import 'package:PiliPlus/pages/music/video/controller.dart';
|
||||
import 'package:PiliPlus/pages/music/widget/music_video_card_h.dart';
|
||||
import 'package:PiliPlus/utils/grid.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MusicRecommandPage extends StatefulWidget {
|
||||
const MusicRecommandPage({super.key});
|
||||
|
||||
@override
|
||||
State<MusicRecommandPage> createState() => _MusicRecommandPageState();
|
||||
}
|
||||
|
||||
class _MusicRecommandPageState extends State<MusicRecommandPage>
|
||||
with GridMixin, SingleTickerProviderStateMixin {
|
||||
late final _controller = Get.put(
|
||||
MusicRecommendController(),
|
||||
tag: Utils.generateRandomString(8),
|
||||
);
|
||||
|
||||
late final _animation = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(seconds: 5),
|
||||
reverseDuration: const Duration(seconds: 5),
|
||||
)..repeat(reverse: true);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final padding = MediaQuery.viewPaddingOf(context);
|
||||
return Material(
|
||||
color: theme.colorScheme.surface,
|
||||
child: refreshIndicator(
|
||||
onRefresh: _controller.onRefresh,
|
||||
child: CustomScrollView(
|
||||
controller: _controller.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
_buildAppBar(theme, padding),
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
top: 7,
|
||||
left: padding.left,
|
||||
right: padding.right,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
sliver: Obx(
|
||||
() => _buildBody(_controller.loadingState.value),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody(LoadingState<List<BgmRecommend>?> loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => gridSkeleton,
|
||||
Success(:var response) =>
|
||||
response?.isNotEmpty == true
|
||||
? SliverGrid.builder(
|
||||
gridDelegate: gridDelegate,
|
||||
itemBuilder: (context, index) => MusicVideoCardH(
|
||||
videoItem: response[index],
|
||||
animation: _animation,
|
||||
),
|
||||
itemCount: response!.length,
|
||||
)
|
||||
: HttpError(onReload: _controller.onReload),
|
||||
Error(:var errMsg) => HttpError(
|
||||
errMsg: errMsg,
|
||||
onReload: _controller.onReload,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Widget _buildAppBar(ThemeData theme, EdgeInsets padding) {
|
||||
final info = _controller.musicDetail;
|
||||
return SliverAppBar(
|
||||
pinned: true,
|
||||
title: Row(
|
||||
spacing: 12,
|
||||
children: [
|
||||
NetworkImgLayer(
|
||||
width: 40,
|
||||
height: 40,
|
||||
src: info.mvCover,
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
info.musicTitle!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.textTheme.titleMedium,
|
||||
),
|
||||
Obx(() {
|
||||
final count = _controller.loadingState.value.dataOrNull?.length;
|
||||
return count == null
|
||||
? const SizedBox.shrink()
|
||||
: Text(
|
||||
'共$count条视频',
|
||||
style: theme.textTheme.labelMedium,
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_animation.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user