You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
8.5 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_bloc/flutter_bloc.dart';
  3. import 'package:flutter_riverpod/flutter_riverpod.dart';
  4. import 'package:image_picker/image_picker.dart';
  5. import 'package:my_flutter_puzzle/application/states/image_splitter_state.dart';
  6. import 'package:my_flutter_puzzle/application/states/puzzle_state.dart';
  7. import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart';
  8. import 'package:my_flutter_puzzle/models/puzzle_data.dart';
  9. import 'package:my_flutter_puzzle/providers.dart';
  10. import 'package:my_flutter_puzzle/res/puzzle_constants.dart';
  11. import 'package:my_flutter_puzzle/utils/puzzle_solver.dart';
  12. import 'package:my_flutter_puzzle/utils/utils.dart';
  13. import 'package:my_flutter_puzzle/widgets/photo_screen/image_viewer.dart';
  14. import 'package:my_flutter_puzzle/widgets/solo_screen/count_down_timer_widget.dart';
  15. import 'package:my_flutter_puzzle/widgets/solo_screen/solo_screen_export.dart';
  16. import 'package:palette_generator/palette_generator.dart';
  17. import 'package:rive/rive.dart';
  18. class PhotoScreenLarge extends ConsumerStatefulWidget {
  19. const PhotoScreenLarge({
  20. required this.solverClient,
  21. required this.initialPuzzleData,
  22. required this.puzzleSize,
  23. required this.riveController,
  24. required this.duration,
  25. Key? key,
  26. }) : super(key: key);
  27. final PuzzleSolverClient solverClient;
  28. final PuzzleData initialPuzzleData;
  29. final int puzzleSize;
  30. final int duration;
  31. final RiveAnimationController riveController;
  32. @override
  33. ConsumerState<ConsumerStatefulWidget> createState() => _SoloScreenLargeState();
  34. }
  35. class _SoloScreenLargeState extends ConsumerState<PhotoScreenLarge> {
  36. late final PuzzleSolverClient _solverClient;
  37. late final int _puzzleSize;
  38. late final PuzzleData _initialPuzzleData;
  39. late final RiveAnimationController _riveController;
  40. bool _puzzleSolved = false;
  41. bool _isStartPressed = false;
  42. final _imagePicker = ImagePicker();
  43. final double _fontSize = 70.0;
  44. final double _boardSize = 280.0;
  45. final int _spacing = 4;
  46. late double _eachBoxSize;
  47. List<Image>? _previousImages;
  48. Image? _previousImage;
  49. PaletteGenerator? _previousPalette;
  50. @override
  51. void initState() {
  52. _solverClient = widget.solverClient;
  53. _puzzleSize = widget.puzzleSize;
  54. _eachBoxSize = (_boardSize / _puzzleSize) - (_spacing * (_puzzleSize - 1));
  55. _initialPuzzleData = widget.initialPuzzleData;
  56. _riveController = widget.riveController;
  57. super.initState();
  58. }
  59. @override
  60. Widget build(BuildContext context) {
  61. ref.listen(puzzleNotifierProvider(_solverClient), (previous, PuzzleState next) {
  62. if (next is PuzzleInitializing) {
  63. setState(() {
  64. _isStartPressed = true;
  65. });
  66. }
  67. if (next is PuzzleSolved) {
  68. _puzzleSolved = true;
  69. }
  70. });
  71. ref.listen(imageSplitterNotifierProvider, (previous, next) {
  72. if (next is ImageSplitterComplete) {
  73. setState(() {
  74. _previousImages = next.images;
  75. _previousImage = next.image;
  76. _previousPalette = next.palette;
  77. });
  78. }
  79. });
  80. return WillPopScope(
  81. onWillPop: () async {
  82. BlocProvider.of<CountDownTimerCubit>(context).stop();
  83. return true;
  84. },
  85. child: Scaffold(
  86. backgroundColor: Theme.of(context).colorScheme.background,
  87. body: SafeArea(
  88. child: Row(
  89. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  90. children: [
  91. Padding(
  92. padding: const EdgeInsetsDirectional.symmetric(horizontal: 10),
  93. child: Column(
  94. mainAxisAlignment: MainAxisAlignment.center,
  95. crossAxisAlignment: CrossAxisAlignment.center,
  96. children: [
  97. const SizedBox(height: 32),
  98. MovesTilesWidget(solverClient: _solverClient, fontSize: 16),
  99. const SizedBox(height: 32),
  100. GameButtonWidget(
  101. solverClient: _solverClient,
  102. initialPuzzleData: _initialPuzzleData,
  103. ),
  104. ],
  105. ),
  106. ),
  107. SingleChildScrollView(
  108. child: Column(
  109. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  110. children: [
  111. CountDownTimerWidget(
  112. duration: widget.duration,
  113. finishCallback: () {
  114. if (!_puzzleSolved) {
  115. Utils.instance.showToast(context, 'TimeOut');
  116. Future.delayed(const Duration(milliseconds: 1500), () {
  117. Navigator.pop(context);
  118. });
  119. }
  120. },
  121. ),
  122. const SizedBox(height: 12),
  123. Consumer(
  124. builder: (context, ref, child) {
  125. final state = ref.watch(imageSplitterNotifierProvider);
  126. return state.maybeWhen(
  127. () => PuzzleWidget(
  128. solverClient: _solverClient,
  129. boardSize: _boardSize,
  130. eachBoxSize: _eachBoxSize,
  131. initialPuzzleData: _initialPuzzleData,
  132. fontSize: _fontSize,
  133. images: _previousImages,
  134. kInitialSpeed: kInitialSpeed,
  135. ),
  136. complete: (image, images, palette) {
  137. _previousImages = images;
  138. _previousImage = image;
  139. _previousPalette = palette;
  140. return PuzzleWidget(
  141. solverClient: _solverClient,
  142. boardSize: _boardSize,
  143. eachBoxSize: _eachBoxSize,
  144. initialPuzzleData: _initialPuzzleData,
  145. fontSize: _fontSize,
  146. images: images,
  147. kInitialSpeed: kInitialSpeed,
  148. );
  149. },
  150. orElse: () => PuzzleWidget(
  151. solverClient: _solverClient,
  152. boardSize: _boardSize,
  153. eachBoxSize: _eachBoxSize,
  154. initialPuzzleData: _initialPuzzleData,
  155. fontSize: _fontSize,
  156. images: _previousImages,
  157. kInitialSpeed: kInitialSpeed,
  158. ),
  159. );
  160. },
  161. ),
  162. const SizedBox(height: 30),
  163. ],
  164. ),
  165. ),
  166. Padding(
  167. padding: const EdgeInsetsDirectional.symmetric(horizontal: 10),
  168. child: Stack(
  169. children: [
  170. AnimatedDash(
  171. boardSize: _boardSize * 0.8,
  172. riveController: _riveController,
  173. onInit: (_) => setState(() {}),
  174. ),
  175. Column(
  176. mainAxisSize: MainAxisSize.max,
  177. crossAxisAlignment: CrossAxisAlignment.end,
  178. mainAxisAlignment: MainAxisAlignment.center,
  179. children: [
  180. CountdownWidget(
  181. isStartPressed: _isStartPressed,
  182. onFinish: () {
  183. // ref.read(timerNotifierProvider.notifier).startTimer();
  184. BlocProvider.of<CountDownTimerCubit>(context).start();
  185. setState(() {
  186. _isStartPressed = false;
  187. });
  188. },
  189. initialSpeed: kInitialSpeed,
  190. ),
  191. Visibility(
  192. visible: !_isStartPressed,
  193. child: ImageViewer(
  194. imagePicker: _imagePicker,
  195. puzzleSize: _puzzleSize,
  196. previousImage: _previousImage,
  197. previousPalette: _previousPalette,
  198. imageSize: 200,
  199. ),
  200. ),
  201. ],
  202. ),
  203. ],
  204. ),
  205. ),
  206. ],
  207. ),
  208. ),
  209. ),
  210. );
  211. }
  212. }