// Author: fruit.com.cn import 'package:flutter/material.dart'; import '../../../core/data/models/drama.dart'; import '../../../core/theme/app_colors.dart'; const double _cellRadius = 8; const double _numberSize = 15; const double _lockSize = 16; const double _lockGap = 4; const double _lockWeight = 300; const double _coverAlpha = 0.55; /// 选集格子。需要解锁时铺一层透明底,锁在上,集数在锁下面。 class EpisodePickerCell extends StatelessWidget { const EpisodePickerCell({ required this.episode, required this.selected, required this.lockLabel, required this.onTap, super.key, }); final Episode episode; final bool selected; final String lockLabel; final VoidCallback onTap; @override Widget build(BuildContext context) { return Material( clipBehavior: Clip.antiAlias, color: selected ? AppColors.bluePressed : AppColors.raised, borderRadius: BorderRadius.circular(_cellRadius), child: InkWell( onTap: onTap, child: Stack( fit: StackFit.expand, children: [ if (!episode.locked) Center( child: _EpisodeNumber( episode.number, color: selected ? AppColors.onPrimary : AppColors.cream, ), ), if (episode.locked) _LockCover( episodeId: episode.id, number: episode.number, label: lockLabel, selected: selected, ), ], ), ), ); } } class _EpisodeNumber extends StatelessWidget { const _EpisodeNumber(this.number, {required this.color}); final int number; final Color color; @override Widget build(BuildContext context) { return Text( '$number', style: TextStyle( color: color, fontSize: _numberSize, fontWeight: FontWeight.w600, height: 1, ), ); } } /// 透明底铺满格子,锁在上,集数在锁下面。 class _LockCover extends StatelessWidget { const _LockCover({ required this.episodeId, required this.number, required this.label, required this.selected, }); final String episodeId; final int number; final String label; final bool selected; @override Widget build(BuildContext context) { return Stack( fit: StackFit.expand, children: [ ColoredBox( key: ValueKey('episode-lock-cover-$episodeId'), color: AppColors.card.withValues(alpha: _coverAlpha), ), Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.lock_outline, key: ValueKey('episode-lock-$episodeId'), size: _lockSize, weight: _lockWeight, fill: 0, color: AppColors.secondary, semanticLabel: label, ), const SizedBox(height: _lockGap), _EpisodeNumber( number, color: selected ? AppColors.onPrimary : AppColors.cream, ), ], ), ), ], ); } }