import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/components/image/universal_image.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/string.dart'; class PlaybuttonTile extends StatelessWidget { final void Function()? onTap; final void Function()? onPlaybuttonPressed; final void Function()? onAddToQueuePressed; final String? description; final String? imageUrl; final Widget? image; final bool isPlaying; final bool isLoading; final String title; final bool isOwner; const PlaybuttonTile({ required this.isPlaying, required this.isLoading, required this.title, this.description, this.onPlaybuttonPressed, this.onAddToQueuePressed, this.onTap, this.isOwner = false, this.imageUrl, this.image, super.key, }) : assert( imageUrl != null || image != null, "imageUrl and image can't be null at the same time", ); @override Widget build(BuildContext context) { final cleanDescription = description?.unescapeHtml().cleanHtml() ?? ""; final scale = context.theme.scaling; return Button( leading: imageUrl != null ? Container( width: 50 * scale, height: 50 * scale, decoration: BoxDecoration( borderRadius: context.theme.borderRadiusMd, image: DecorationImage( image: UniversalImage.imageProvider(imageUrl!), fit: BoxFit.cover, ), ), ) : SizedBox( width: 50 * scale, height: 50 * scale, child: ClipRRect( borderRadius: context.theme.borderRadiusMd, child: image, ), ), style: ButtonVariance.ghost.copyWith( padding: (context, states, value) { return (ButtonVariance.ghost.padding(context, states) as EdgeInsets) .copyWith(right: 0, left: 0); }, ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Tooltip( tooltip: TooltipContainer(child: Text(context.l10n.add_to_queue)).call, child: IconButton.outline( icon: const Icon(SpotubeIcons.queueAdd), onPressed: onAddToQueuePressed, enabled: !isLoading, ), ), const Gap(8), Tooltip( tooltip: TooltipContainer(child: Text(context.l10n.play)).call, child: IconButton.secondary( icon: switch ((isLoading, isPlaying)) { (true, _) => const CircularProgressIndicator( size: 22, ), (false, false) => const Icon(SpotubeIcons.play), (false, true) => const Icon(SpotubeIcons.pause) }, onPressed: onPlaybuttonPressed, enabled: !isLoading, ), ), ], ), enabled: !isLoading, onPressed: onTap, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title), if (cleanDescription.isNotEmpty) Text( description!, maxLines: 2, overflow: TextOverflow.ellipsis, ).xSmall().muted(), ], ), ); } }