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 createState() { return _DramaEspPageState(); } } class _DramaEspPageState extends State { late int _selectedEpisode; SkywoodDrama? get _drama => widget.detail.shortPlayInfo ?? widget.detail.videoInfo; List 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; } }