feat: 播放处理,个人中心,

This commit is contained in:
chengsiwen committed 2026-06-30 16:05:17 +08:00
1 parent e59ac2177b
commit 4ccea08472
37 files changed
+1425 -115

No files matched your search

@@ -1,9 +1,13 @@
import 'package:flutter/material.dart';
import 'package:skywood/global/client/play_client.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/pages/home/players/widget/player_bottom_widget.dart';
import 'package:skywood/pages/home/players/widget/sky_player_view.dart';
import 'package:skywood/utils/models/drama/skywood_detail.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/models/drama/skywood_home.dart';
import 'package:skywood/utils/tools/widgets/sky_app_bar.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class DramaDetailPage extends StatefulWidget {
const DramaDetailPage({super.key,
@@ -20,28 +24,30 @@ class DramaDetailPage extends StatefulWidget {
class _DramaDetailPageState extends State<DramaDetailPage> {
SkywoodDetail? _detailBean;
@override
void initState() {
super.initState();
// _getDetailDrama();
_getDetailDrama();
}
// void _getDetailDrama() {
// PlayClient.getVideoDetail(
// shortPlayId: widget.shortPlayId,
// shortPlayVideoId: widget.shortPlayVideoId
// ).then((value) {});
// }
void _getDetailDrama() {
PlayClient.getVideoDetail(
shortPlayId: widget.dramaBean.shortPlayId ?? 0,
shortPlayVideoId: widget.dramaBean.shortPlayVideoId ?? 0
).then((value) {
setState(() {
_detailBean = value;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: SkyAppBar(
title: widget.dramaBean.name,
backgroundColor: Colors.transparent,
),
body: _bodyWidget(),
);
}
@@ -50,11 +56,43 @@ class _DramaDetailPageState extends State<DramaDetailPage> {
return Stack(
children: [
SizedBox(width: double.infinity, height: double.infinity),
if (widget.dramaBean.videoUrl != null)
Positioned(
bottom: 0, left: 0, right: 0, top: 0,
child: SkyPlayerView(
videoUrl: widget.dramaBean.videoUrl!,
detailBean: _detailBean,
dramaBean: widget.dramaBean,
),
),
Positioned(
bottom: 0, left: 0, right: 0,
child: PlayerBottomWidget(),
),
top: AppScreen.statusBarHeight + 5, left: 0, right: 0,
child: _headerWidget(),
)
],
);
}
Widget _headerWidget() {
return Container(
height: 40,
padding: const EdgeInsets.only(right: 15, left: 5),
child: Row(
children: [
IconButton(
icon: HelpImg.asset(ConstImg.back, width: 32),
onPressed: () => HelpNav.back(),
),
Expanded(child: SkyText(text: widget.dramaBean.name, color: Colors.white, fontSize: 16,
textAlign: TextAlign.center,
fontWeight: FontWeight.bold,
)),
SizedBox(width: 40,)
],
),
);
}
}
@@ -0,0 +1,220 @@
import 'package:flutter/material.dart';
import 'package:skywood/main/lib_file.dart';
import 'package:skywood/utils/models/drama/skywood_detail.dart';
import 'package:skywood/utils/models/drama/skywood_drama.dart';
import 'package:skywood/utils/models/drama/skywood_episode.dart';
import 'package:skywood/utils/tools/widgets/sky_common_widget.dart';
class DramaEspPage extends StatefulWidget {
const DramaEspPage({super.key, required this.detail, this.currentEpisode});
final SkywoodDetail detail;
final int? currentEpisode;
@override
State<StatefulWidget> createState() {
return _DramaEspPageState();
}
}
class _DramaEspPageState extends State<DramaEspPage> {
late int _selectedEpisode;
SkywoodDrama? get _drama =>
widget.detail.shortPlayInfo ?? widget.detail.videoInfo;
List<SkywoodEpisode> get _episodes => widget.detail.episodeList;
@override
void initState() {
super.initState();
_selectedEpisode = widget.currentEpisode ?? _drama?.episode ?? 1;
}
@override
Widget build(BuildContext context) {
final double height = 520;
return SizedBox(
width: AppScreen.screenWidth,
height: 520,
child: Stack(
children: [
HelpImg.asset(
ConstImg.espBg,
width: AppScreen.screenWidth,
height: height,
fit: BoxFit.fill,
),
Positioned.fill(
child: Padding(
padding: EdgeInsets.fromLTRB(22.w, 31.h, 22.w, 54.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDramaInfo(),
SizedBox(height: 12),
Divider(
height: 1,
thickness: 0.5,
color: Colors.black.withAlpha(18),
),
SizedBox(height: 12),
SkyText(
text: '$_episodeTotal EP',
color: Colors.black,
fontSize: 15,
fontWeight: FontWeight.w500,
),
SizedBox(height: 8),
Expanded(child: _buildEpisodeGrid()),
],
),
),
),
],
),
);
}
Widget _buildDramaInfo() {
final SkywoodDrama? drama = _drama;
final SkywoodDrama? info = widget.detail.videoInfo;
final String imageUrl = drama?.imageUrl ?? '';
return SizedBox(
height: 130.h,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
HelpImg.networkRadius(
imageUrl,
width: 96.w,
height: 130.h,
fit: BoxFit.cover,
borderRadius: BorderRadius.circular(2),
),
SizedBox(width: 16.w),
Expanded(
child: Padding(
padding: EdgeInsets.only(top: 7.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SkyText(
text: drama?.name ?? '',
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w700,
maxLines: 2,
lineHeight: 1.12,
),
SizedBox(height: 10.h),
SkyText(
text: info?.description ?? '',
color: Colors.black.withAlpha(118),
fontSize: 14,
maxLines: 2,
lineHeight: 1.45,
),
SizedBox(height: 13.h),
_buildTag(),
],
),
),
),
],
),
);
}
Widget _buildTag() {
final String name = _drama?.categoryList?.isNotEmpty == true
? _drama!.categoryList!.first.name
: (_drama?.tagType ?? '');
if (name.isEmpty) return const SizedBox.shrink();
return Container(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 3.h),
decoration: BoxDecoration(
color: const Color(0xFFE7FFE5),
border: Border.all(color: const Color(0xFF86D57A), width: 1),
),
child: SkyText(
text: name,
color: Colors.black,
fontSize: 14,
overflow: TextOverflow.visible,
),
);
}
Widget _buildEpisodeGrid() {
if (_episodes.isEmpty) {
return const SizedBox.shrink();
}
return GridView.builder(
padding: EdgeInsets.zero,
physics: const BouncingScrollPhysics(),
itemCount: _episodes.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 61 / 50,
),
itemBuilder: (context, index) {
return _buildEpisodeItem(_episodes[index]);
},
);
}
Widget _buildEpisodeItem(SkywoodEpisode episode) {
final bool selected = episode.episode == _selectedEpisode;
final bool selectedPlayable = selected && !episode.isLock;
final bool selectedLocked = selected && episode.isLock;
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
_selectedEpisode = episode.episode;
});
},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: selectedPlayable
? const Color(0xFF91F476)
: const Color(0xFFF8F8F8),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: selectedPlayable
? Colors.black
: (selectedLocked
? CommonColor.primacyColor
: Colors.transparent),
width: selected ? 1 : 0,
),
),
child: Center(
child: SkyText(
text: episode.episode.toString(),
color: Colors.black.withAlpha(220),
fontSize: 20,
fontWeight: selected ? FontWeight.w700 : FontWeight.w400,
),
),
),
);
}
int get _episodeTotal {
if (_drama?.episodeTotal != null && _drama!.episodeTotal > 0) {
return _drama!.episodeTotal;
}
return _episodes.length;
}
}