Mobile/lib/presentation/home_page/card.dart

185 lines
5.6 KiB
Dart
Raw Normal View History

2024-10-16 16:13:47 +04:00
part of 'home_page.dart';
typedef OnLikeCallback = void Function(String title, bool isLiked)?;
class CardData {
final String text;
final String description;
final IconData icon;
2024-11-18 15:06:34 +04:00
final double score;
2024-10-16 16:13:47 +04:00
final String imageUrl;
const CardData(
2024-11-18 15:06:34 +04:00
this.text,
this.score, {
2024-10-16 16:13:47 +04:00
required this.description,
this.icon = Icons.add_call,
this.imageUrl =
"https://i.pinimg.com/736x/5f/14/b3/5f14b3f14fcd157bc4dffa39085396cc.jpg",
});
}
class _Card extends StatefulWidget {
final String text;
final String description;
final String? imageUrl;
2024-11-18 15:06:34 +04:00
final double score;
2024-10-16 16:13:47 +04:00
final OnLikeCallback onLike;
final VoidCallback? onTap;
const _Card(
this.text, {
required this.description,
required this.imageUrl,
2024-11-18 15:06:34 +04:00
required this.score,
2024-10-16 16:13:47 +04:00
this.onLike,
this.onTap,
});
factory _Card.fromData(
CardData data, {
OnLikeCallback onLike,
VoidCallback? onTap,
}) =>
_Card(
data.text,
description: data.description,
imageUrl: data.imageUrl,
2024-11-18 15:06:34 +04:00
score: data.score,
2024-10-16 16:13:47 +04:00
onLike: onLike,
onTap: onTap,
);
@override
State<_Card> createState() => _CardState();
}
class _CardState extends State<_Card> {
bool isLiked = false;
@override
Widget build(BuildContext context) {
2024-11-18 15:06:34 +04:00
List<String> desc = widget.description.split("\n");
2024-10-16 16:13:47 +04:00
return GestureDetector(
onTap: widget.onTap,
child: Container(
margin: const EdgeInsets.all(10),
constraints: const BoxConstraints(minHeight: 140),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.green, width: 2),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(.4),
offset: const Offset(0, 5),
blurRadius: 6,
spreadRadius: 3),
]),
child: IntrinsicHeight(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(children: [
ClipRRect(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(18),
topLeft: Radius.circular(18),
),
child: SizedBox(
2024-11-18 15:06:34 +04:00
height: 300,
2024-10-16 16:13:47 +04:00
width: 120,
child: Image.network(
widget.imageUrl ?? '',
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => const Placeholder(),
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
decoration: const BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
bottomLeft: Radius.circular(18))),
padding: const EdgeInsets.fromLTRB(8, 2, 8, 2),
2024-11-18 15:06:34 +04:00
child: Text(generateStars(widget.score),
2024-10-16 16:13:47 +04:00
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(color: Colors.white)),
),
),
]),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
widget.text,
2024-11-18 15:06:34 +04:00
style: Theme.of(context).textTheme.headlineMedium,
2024-10-16 16:13:47 +04:00
),
Text(
2024-11-18 15:06:34 +04:00
desc[0],
2024-10-16 16:13:47 +04:00
style: Theme.of(context).textTheme.bodySmall,
)
],
),
),
),
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.only(
left: 8,
right: 8,
bottom: 8,
),
child: GestureDetector(
onTap: () {
setState(() => isLiked = !isLiked);
widget.onLike?.call(widget.text, isLiked);
},
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
child: isLiked
? const Icon(
Icons.favorite,
color: Colors.red,
key: ValueKey<int>(0),
)
: const Icon(
Icons.favorite_border,
key: ValueKey<int>(1),
),
),
)),
)
],
),
),
),
);
}
}
2024-11-18 15:06:34 +04:00
String generateStars(double rating) {
rating = rating / 2;
int fullStars = rating.floor();
bool hasHalfStar = (rating - fullStars) >= 0.5;
String stars = '' * fullStars;
if (hasHalfStar) {
stars += '';
}
int emptyStars = 5 - stars.length;
stars += '' * emptyStars;
return stars;
}