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.

242 lines
9.1 KiB

2 years ago
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import 'package:image_picker/image_picker.dart';
  4. import 'package:my_flutter_puzzle/application/states/image_splitter_state.dart';
  5. import 'package:my_flutter_puzzle/application/states/puzzle_state.dart';
  6. import 'package:my_flutter_puzzle/models/puzzle_data.dart';
  7. import 'package:my_flutter_puzzle/providers.dart';
  8. import 'package:my_flutter_puzzle/res/puzzle_constants.dart';
  9. import 'package:my_flutter_puzzle/utils/puzzle_solver.dart';
  10. import 'package:my_flutter_puzzle/widgets/photo_screen/image_viewer.dart';
  11. import 'package:my_flutter_puzzle/widgets/photo_screen/pick_image_button.dart';
  12. import 'package:my_flutter_puzzle/widgets/solo_screen/countdown_overlay.dart';
  13. import 'package:my_flutter_puzzle/widgets/solo_screen/solo_screen_export.dart';
  14. import 'package:palette_generator/palette_generator.dart';
  15. import 'package:rive/rive.dart';
  16. class PhotoScreenSmall extends ConsumerStatefulWidget {
  17. const PhotoScreenSmall({
  18. required this.solverClient,
  19. required this.initialPuzzleData,
  20. required this.puzzleSize,
  21. required this.riveController,
  22. Key? key,
  23. }) : super(key: key);
  24. final PuzzleSolverClient solverClient;
  25. final PuzzleData initialPuzzleData;
  26. final int puzzleSize;
  27. final RiveAnimationController riveController;
  28. @override
  29. ConsumerState<ConsumerStatefulWidget> createState() => _SoloScreenLargeState();
  30. }
  31. class _SoloScreenLargeState extends ConsumerState<PhotoScreenSmall> {
  32. late final PuzzleSolverClient _solverClient;
  33. late final int _puzzleSize;
  34. late final PuzzleData _initialPuzzleData;
  35. late final RiveAnimationController _riveController;
  36. bool _isStartPressed = false;
  37. final _imagePicker = ImagePicker();
  38. List<Image>? _previousImages;
  39. Image? _previousImage;
  40. PaletteGenerator? _previousPalette;
  41. @override
  42. void initState() {
  43. _solverClient = widget.solverClient;
  44. _puzzleSize = widget.puzzleSize;
  45. _initialPuzzleData = widget.initialPuzzleData;
  46. _riveController = widget.riveController;
  47. super.initState();
  48. }
  49. @override
  50. Widget build(BuildContext context) {
  51. ref.listen(puzzleNotifierProvider(_solverClient), (previous, PuzzleState next) {
  52. if (next is PuzzleInitializing) {
  53. setState(() {
  54. _isStartPressed = true;
  55. });
  56. }
  57. });
  58. ref.listen(imageSplitterNotifierProvider, (previous, next) {
  59. if (next is ImageSplitterComplete) {
  60. setState(() {
  61. _previousImages = next.images;
  62. _previousImage = next.image;
  63. _previousPalette = next.palette;
  64. });
  65. }
  66. });
  67. var fontSize = 48.0;
  68. var boardSize = 300.0;
  69. var spacing = 2;
  70. var eachBoxSize = (boardSize / _puzzleSize) - (spacing * (_puzzleSize - 1));
  71. return Stack(
  72. children: [
  73. Scaffold(
  74. backgroundColor: Theme.of(context).colorScheme.background,
  75. // appBar: PreferredSize(
  76. // child: Container(
  77. // color: Theme.of(context).colorScheme.background,
  78. // ),
  79. // preferredSize: const Size(double.maxFinite, 30),
  80. // ),
  81. body: Stack(
  82. children: [
  83. // CountdownWidget(
  84. // isStartPressed: _isStartPressed,
  85. // onFinish: () {
  86. // ref.read(timerNotifierProvider.notifier).startTimer();
  87. // setState(() {
  88. // _isStartPressed = false;
  89. // });
  90. // },
  91. // initialSpeed: kInitialSpeed,
  92. // ),
  93. Row(
  94. children: [
  95. const Spacer(),
  96. AnimatedDash(
  97. boardSize: boardSize / 1.6,
  98. riveController: _riveController,
  99. onInit: (_) => setState(() {}),
  100. padding: const EdgeInsets.only(right: 16.0, bottom: 30),
  101. ),
  102. ],
  103. ),
  104. SingleChildScrollView(
  105. child: Column(
  106. mainAxisAlignment: MainAxisAlignment.center,
  107. // crossAxisAlignment: CrossAxisAlignment.start,
  108. children: [
  109. Row(),
  110. // Text(
  111. // _puzzleType,
  112. // style: const TextStyle(
  113. // fontSize: 18,
  114. // fontWeight: FontWeight.w500,
  115. // color: Colors.white,
  116. // ),
  117. // ),
  118. const SizedBox(height: 30),
  119. const Text(
  120. 'Puzzle Challenge',
  121. style: TextStyle(
  122. fontSize: 32,
  123. fontWeight: FontWeight.w500,
  124. color: Colors.white,
  125. ),
  126. ),
  127. const SizedBox(height: 8),
  128. MovesTilesWidget(
  129. solverClient: _solverClient,
  130. fontSize: 22,
  131. ),
  132. const SizedBox(height: 8),
  133. const TimerWidget(fontSize: 24),
  134. Consumer(
  135. builder: (context, ref, child) {
  136. final state = ref.watch(imageSplitterNotifierProvider);
  137. return state.maybeWhen(
  138. () => PuzzleWidget(
  139. solverClient: _solverClient,
  140. boardSize: boardSize,
  141. eachBoxSize: eachBoxSize,
  142. initialPuzzleData: _initialPuzzleData,
  143. fontSize: fontSize,
  144. images: _previousImages,
  145. kInitialSpeed: kInitialSpeed,
  146. borderRadius: 16,
  147. ),
  148. complete: (image, images, palette) {
  149. _previousImages = images;
  150. _previousImage = image;
  151. _previousPalette = palette;
  152. return PuzzleWidget(
  153. solverClient: _solverClient,
  154. boardSize: boardSize,
  155. eachBoxSize: eachBoxSize,
  156. initialPuzzleData: _initialPuzzleData,
  157. fontSize: fontSize,
  158. images: images,
  159. kInitialSpeed: kInitialSpeed,
  160. borderRadius: 16,
  161. );
  162. },
  163. orElse: () => PuzzleWidget(
  164. solverClient: _solverClient,
  165. boardSize: boardSize,
  166. eachBoxSize: eachBoxSize,
  167. initialPuzzleData: _initialPuzzleData,
  168. fontSize: fontSize,
  169. images: _previousImages,
  170. kInitialSpeed: kInitialSpeed,
  171. borderRadius: 16,
  172. ),
  173. );
  174. },
  175. ),
  176. const SizedBox(height: 24),
  177. Row(
  178. mainAxisSize: MainAxisSize.min,
  179. children: [
  180. GameButtonWidget(
  181. solverClient: _solverClient,
  182. initialPuzzleData: _initialPuzzleData,
  183. padding: const EdgeInsets.only(top: 10.0, bottom: 9.0),
  184. width: 130,
  185. ),
  186. const SizedBox(width: 16),
  187. PickImageButton(
  188. text: 'Pick Image',
  189. onTap: ref.read(imageSplitterNotifierProvider) is ImageSplitterComplete
  190. ? () => ref.read(imageSplitterNotifierProvider.notifier).generateImages(
  191. picker: _imagePicker,
  192. puzzleSize: _puzzleSize,
  193. )
  194. : null,
  195. padding: const EdgeInsets.only(top: 10.0, bottom: 9.0),
  196. width: 130,
  197. ),
  198. ],
  199. ),
  200. const SizedBox(height: 16),
  201. ImageViewer(
  202. imagePicker: _imagePicker,
  203. puzzleSize: _puzzleSize,
  204. previousImage: _previousImage,
  205. previousPalette: _previousPalette,
  206. imageSize: 110,
  207. ),
  208. const SizedBox(height: 50),
  209. ],
  210. ),
  211. ),
  212. ],
  213. ),
  214. ),
  215. CountdownOverlay(
  216. isStartPressed: _isStartPressed,
  217. onFinish: () {
  218. ref.read(timerNotifierProvider.notifier).startTimer();
  219. setState(() {
  220. _isStartPressed = false;
  221. });
  222. },
  223. initialSpeed: kInitialSpeed,
  224. ),
  225. ],
  226. );
  227. }
  228. }