import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:my_flutter_puzzle/application/states/image_splitter_state.dart'; import 'package:my_flutter_puzzle/application/states/puzzle_state.dart'; import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart'; import 'package:my_flutter_puzzle/models/puzzle_data.dart'; import 'package:my_flutter_puzzle/providers.dart'; import 'package:my_flutter_puzzle/res/puzzle_constants.dart'; import 'package:my_flutter_puzzle/screens/level_list/cubit/level_list_cubit.dart'; import 'package:my_flutter_puzzle/screens/lose/lose_screen.dart'; import 'package:my_flutter_puzzle/screens/win/win_screen.dart'; import 'package:my_flutter_puzzle/utils/extensions/context_extension.dart'; import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; import 'package:my_flutter_puzzle/utils/puzzle_solver.dart'; import 'package:my_flutter_puzzle/widgets/photo_screen/image_viewer.dart'; import 'package:my_flutter_puzzle/widgets/solo_screen/count_down_timer_widget.dart'; import 'package:my_flutter_puzzle/widgets/solo_screen/countdown_widget.dart'; import 'package:my_flutter_puzzle/widgets/solo_screen/moves_tiles_widget.dart'; import 'package:my_flutter_puzzle/widgets/solo_screen/puzzle_widget.dart'; import 'package:palette_generator/palette_generator.dart'; import 'package:rive/rive.dart'; class PhotoScreenLarge extends ConsumerStatefulWidget { const PhotoScreenLarge({ required this.solverClient, required this.initialPuzzleData, required this.puzzleSize, required this.riveController, required this.duration, required this.level, Key? key, }) : super(key: key); final PuzzleSolverClient solverClient; final PuzzleData initialPuzzleData; final int puzzleSize; final int duration; final int level; final RiveAnimationController riveController; @override ConsumerState createState() => _SoloScreenLargeState(); } class _SoloScreenLargeState extends ConsumerState { late final PuzzleSolverClient _solverClient; late final int _puzzleSize; late final PuzzleData _initialPuzzleData; late final RiveAnimationController _riveController; bool _puzzleSolved = false; bool _isStartPressed = false; final double _fontSize = 70.0; final double _boardSize = 280.0; final int _spacing = 4; late double _eachBoxSize; List? _previousImages; Image? _previousImage; PaletteGenerator? _previousPalette; int _moves = 0; int _tiles = 0; @override void initState() { _solverClient = widget.solverClient; _puzzleSize = widget.puzzleSize; _eachBoxSize = (_boardSize / _puzzleSize) - (_spacing * (_puzzleSize - 1)); _initialPuzzleData = widget.initialPuzzleData; _riveController = widget.riveController; super.initState(); } @override Widget build(BuildContext context) { ref.listen(puzzleNotifierProvider(_solverClient), (previous, PuzzleState next) { if (next is PuzzleInitializing) { setState(() { _isStartPressed = true; }); } if (next is PuzzleSolved) { _puzzleSolved = true; BlocProvider.of(context).stop(); BlocProvider.of(context).setRecordDuration( widget.level, BlocProvider.of(context).getDuration() ?? Duration(minutes: widget.duration), () { Future.delayed(const Duration(milliseconds: 500), () { Navigator.pushReplacement(context, MaterialPageRoute( builder: (context) { return WinScreen( tiles: _tiles, move: _moves, level: widget.level, ); }, )); }); }, ); } }); ref.listen(imageSplitterNotifierProvider, (previous, next) { if (next is ImageSplitterComplete) { setState(() { _previousImages = next.images; _previousImage = next.image; _previousPalette = next.palette; }); ref.read(puzzleNotifierProvider(_solverClient).notifier).initializePuzzle( initialPuzzleData: _initialPuzzleData, ); } }); return WillPopScope( onWillPop: () async { BlocProvider.of(context).stop(); return true; }, child: Scaffold( backgroundColor: const Color(0xff4400CE), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric( horizontal: context.width * 26 / 812, ), child: Column( children: [ SizedBox(height: context.height * 20 / 375), SizedBox( width: context.width, child: Row( children: [ SvgPicture.asset('flash'.svgPath), const SizedBox(width: 8), Text( 'Level ${widget.level}', style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16, ), ), const Spacer(), CountDownTimerWidget( duration: widget.duration, finishCallback: _finishTime, ), const Spacer(), GestureDetector( onTap: _resetTimer, child: Container( width: context.width * 22 / 540, height: context.width * 22 / 540, padding: const EdgeInsets.all(5), margin: const EdgeInsets.symmetric(vertical: 3), decoration: const BoxDecoration( color: Colors.white, shape: BoxShape.circle, ), child: SvgPicture.asset('refresh'.svgPath), ), ), ], ), ), SizedBox(height: context.height * 22 / 375), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( children: [ ImageViewer( puzzleSize: _puzzleSize, previousImage: _previousImage, previousPalette: _previousPalette, imageSize: 200, ), SizedBox(height: context.height * 30 / 375), MovesTilesWidget( solverClient: _solverClient, fontSize: 16, callback: (move, tiles) { _moves = move; _tiles = tiles; }, ), ], ), SizedBox(width: context.width * 34 / 812), SingleChildScrollView( child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Consumer( builder: (context, ref, child) { final state = ref.watch( imageSplitterNotifierProvider, ); return state.maybeWhen( () => PuzzleWidget( solverClient: _solverClient, boardSize: _boardSize, eachBoxSize: _eachBoxSize, initialPuzzleData: _initialPuzzleData, fontSize: _fontSize, images: _previousImages, kInitialSpeed: kInitialSpeed, ), complete: (image, images, palette) { _previousImages = images; _previousImage = image; _previousPalette = palette; return PuzzleWidget( solverClient: _solverClient, boardSize: _boardSize, eachBoxSize: _eachBoxSize, initialPuzzleData: _initialPuzzleData, fontSize: _fontSize, images: images, kInitialSpeed: kInitialSpeed, ); }, orElse: () => PuzzleWidget( solverClient: _solverClient, boardSize: _boardSize, eachBoxSize: _eachBoxSize, initialPuzzleData: _initialPuzzleData, fontSize: _fontSize, images: _previousImages, kInitialSpeed: kInitialSpeed, ), ); }, ), ], ), ), SizedBox(width: context.width * 32 / 812), Stack( alignment: Alignment.center, children: [ SizedBox( width: context.width * 126 / 812, height: context.height * 280 / 375, child: Image( image: AssetImage('avatar'.pngPath), ), ), Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.center, children: [ CountdownWidget( isStartPressed: _isStartPressed, onFinish: () { BlocProvider.of(context).start(); setState(() { _isStartPressed = false; }); }, initialSpeed: kInitialSpeed, ), ], ), ], ), ], ), ], ), ), ), ), ); } void _finishTime() { if (!_puzzleSolved) { Future.delayed(const Duration(milliseconds: 1500), () { Navigator.push(context, MaterialPageRoute( builder: (context) { return LoseScreen(tiles: _tiles, move: _moves); }, )).then((value) { if (value == true) { BlocProvider.of(context).reset(); BlocProvider.of(context).start(); } else { Navigator.pop(context); } }); }); } } void _resetTimer() { BlocProvider.of(context).reset(); } }