import 'dart:developer'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:mnemo_cards/features/tests/test_manager.dart'; import 'package:mnemo_cards/features/tests/test_widgets/test_image.dart'; import 'package:mnemo_cards/utils/string_helper.dart'; import 'package:mnemo_cards_common/mnemo_cards_common.dart'; import 'package:shimmer/shimmer.dart'; import '../domain/router/app_router.gr.dart'; import '../managers/repository/repository.dart'; import '../theme/themes.dart'; import 'header.dart'; class TestsMenuWidget extends StatefulWidget { final Repository repository; final TestManager testManager; final ScrollController? scrollController; const TestsMenuWidget( this.repository, this.testManager, { this.scrollController, super.key, }); @override State createState() => _TestsMenuWidgetState(); } class _TestsMenuWidgetState extends State { @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { final cardWidth = 125.w; final cardHeight = cardWidth; final theme = Theme.of(context); return FutureBuilder( future: widget.testManager.loadTests(), builder: (context, snapshot) { return Container( alignment: Alignment.topCenter, child: SingleChildScrollView( controller: widget.scrollController, physics: AlwaysScrollableScrollPhysics(), child: Padding( padding: const EdgeInsets.only(top: 8.0), child: Column( children: [ Header('Test'), Padding( padding: const EdgeInsets.all(8.0), child: SizedBox( height: cardHeight + 8, child: ListView( padding: EdgeInsets.all(4.0), scrollDirection: Axis.horizontal, children: [ if (snapshot.data == null) ...[1, 2, 3, 4].map( (e) => _PackButtonShimmer( cardWidth, cardHeight, ), ), if (snapshot.hasData) ...snapshot.data!.map((dto) => _TestButton(dto, cardWidth, cardHeight)), ], ), ), ), ], ), ), ), ); }, ); }); } Future _precache(List packs) async { for (final pack in packs) { // if (pack.dto != null) { // try { // await precacheImage(MemoryImage(pack.cover!), context); // } catch (e) { // log('${pack.dto.id} cover not cached'); // } // } // for (final card in pack.cards.take(3)) { // try { // await precacheImage(card.image, context); // } catch (_) { // log('${pack.dto.id} - ${card.dto.id} image not cached'); // } // } } } } class _CategoryTitle extends StatelessWidget { final String text; _CategoryTitle(this.text); @override Widget build(BuildContext context) { final theme = Theme.of(context).textTheme.titleLarge?.copyWith( fontSize: 28.sp, fontWeight: FontWeight.w800, color: menuBlue, ); return Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(left: 16.0), child: Text( text, style: theme, textAlign: TextAlign.start, ), ); } } class _TestButton extends StatelessWidget { final TestDto dto; final double cardWidth; final double cardHeight; const _TestButton( this.dto, this.cardWidth, this.cardHeight, ); @override Widget build(BuildContext context) { final theme = Theme.of(context); final textTheme = theme.textTheme; return Padding( padding: const EdgeInsets.symmetric(horizontal: 5.0), child: InkWell( onTap: () { AutoRouter.of(context).push( PageRouteInfo(TestPage.name, args: TestPageArgs(testId: dto.id!)), ); }, child: Container( width: cardWidth, height: cardHeight, padding: const EdgeInsets.all(4.0), decoration: BoxDecoration( color: dto.color?.asColor, borderRadius: BorderRadius.circular(12.0), boxShadow: const [ BoxShadow( color: Colors.black26, blurRadius: 4.0, ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( flex: 7, child: (dto.cover != null) ? TestImageWidget(TestImage.image(dto.cover!)) : SizedBox.shrink(), ), Expanded( flex: 3, child: Column( children: [ Text( '18', style: textTheme.headlineSmall ?.copyWith(fontWeight: FontWeight.w800), ), Text('из', style: textTheme.labelLarge ?.copyWith(fontWeight: FontWeight.w800)), Text( '32', style: textTheme.headlineSmall ?.copyWith(fontWeight: FontWeight.w800), ), ], ), ) ], ), FittedBox( fit: BoxFit.scaleDown, child: Padding( padding: const EdgeInsets.all(4.0), child: Text( dto.name, style: theme.textTheme.headlineSmall?.copyWith( fontWeight: FontWeight.w600, fontSize: 16.sp, ), ), ), ), ], ), ), ), ); } } class _PackButtonShimmer extends StatelessWidget { final double cardWidth; final double cardHeight; const _PackButtonShimmer( this.cardWidth, this.cardHeight, ); @override Widget build(BuildContext context) { return Shimmer.fromColors( baseColor: Colors.white, highlightColor: Colors.grey[200]!, child: Container( width: cardWidth, height: cardHeight, child: Padding( padding: const EdgeInsets.all(12.0), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( alignment: Alignment.center, width: cardWidth, height: cardWidth, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.0), )), Container( decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(8.0)), color: Colors.white, ), width: cardWidth * 0.7, height: 30, alignment: Alignment.center, ) ], ), ), ), ); } }