Browse Source

finish work

master
mohsen zamani 2 years ago
parent
commit
31648cf8b8
  1. 2
      android/app/src/main/AndroidManifest.xml
  2. 21
      data/data_core/local_db/local_db_core/lib/boxes/box_list/level_box/level_box.dart
  3. 14
      data/data_types/types/lib/level_data/interface/level_box_repository_impl.dart
  4. 2
      domain/repositories/android/local.properties
  5. 14
      domain/repositories/ios/Flutter/Generated.xcconfig
  6. 13
      domain/repositories/ios/Flutter/flutter_export_environment.sh
  7. 2
      domain/repositories/lib/level_box_domain/adapter/level_model_adapter.dart
  8. 15
      domain/repositories/lib/level_box_domain/model/level_model.dart
  9. 6
      domain/repositories/lib/level_box_domain/repository/level_box_repository.dart
  10. 17
      lib/cubits/count_down_timer_cubit.dart
  11. 1
      lib/initializer.dart
  12. 34
      lib/main.dart
  13. 48
      lib/screens/level_list/cubit/level_list_cubit.dart
  14. 32
      lib/screens/level_list/screen/level_list_screen.dart
  15. 5
      lib/screens/lose/lose_screen.dart
  16. 9
      lib/screens/photo/photo_screen.dart
  17. 46
      lib/screens/photo/photo_screen_large.dart
  18. 5
      lib/screens/splash/screen/splash_screen.dart
  19. 31
      lib/screens/win/win_screen.dart
  20. 80
      lib/widgets/solo_screen/count_down_timer_widget.dart
  21. 2
      lib/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart

2
android/app/src/main/AndroidManifest.xml

@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.souvikbiswas.my_flutter_puzzle"> package="com.souvikbiswas.my_flutter_puzzle">
<application <application
android:label="my_flutter_puzzle"
android:label="Habib Kids"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity

21
data/data_core/local_db/local_db_core/lib/boxes/box_list/level_box/level_box.dart

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:local_db_core/boxes/box_list/level_box/level_box_keys.dart'; import 'package:local_db_core/boxes/box_list/level_box/level_box_keys.dart';
import 'package:local_db_core/boxes/interfaces/base_box_interface.dart'; import 'package:local_db_core/boxes/interfaces/base_box_interface.dart';
@ -29,7 +31,7 @@ class LevelBox implements BaseBoxInterface<LevelBoxKeys> {
_box = await Hive.openBox(getBoxName()); _box = await Hive.openBox(getBoxName());
} }
void updateData({required Level level}) async {
Future<void> updateData({required Level level}) async {
if (!Hive.isBoxOpen(getBoxName())) { if (!Hive.isBoxOpen(getBoxName())) {
await openBox(); await openBox();
} }
@ -60,16 +62,23 @@ class LevelBox implements BaseBoxInterface<LevelBoxKeys> {
if (!Hive.isBoxOpen(getBoxName())) { if (!Hive.isBoxOpen(getBoxName())) {
await openBox(); await openBox();
} }
return _box?.values.cast<Level>().toList() ?? [];
if(_box?.get(getKeyName(LevelBoxKeys.levelList)) == null) {
return [];
}
var data = jsonDecode(_box?.get(getKeyName(LevelBoxKeys.levelList))) ?? [];
List<Level> list = (data).map<Level>((item) {
return Level.fromJson(item);
}).toList();
return list;
} }
Future<void> saveData(List<Level> data) async { Future<void> saveData(List<Level> data) async {
if (!Hive.isBoxOpen(getBoxName())) { if (!Hive.isBoxOpen(getBoxName())) {
await openBox(); await openBox();
} }
_box?.addAll(data);
for (var value in data) {
await value.save();
}
var e = data.map((element) {
return element.toJson();
}).toList();
_box?.put(getKeyName(LevelBoxKeys.levelList), jsonEncode(e));
} }
} }

14
data/data_types/types/lib/level_data/interface/level_box_repository_impl.dart

@ -8,7 +8,7 @@ class LevelBoxRepositoryImpl extends LevelBoxRepository {
LevelBoxRepositoryImpl({required LevelBox levelBox}) : _levelBox = levelBox; LevelBoxRepositoryImpl({required LevelBox levelBox}) : _levelBox = levelBox;
@override @override
Future<void> getLevel({required void Function(List<Level> data) result}) async {
Future<List<Level>> saveBaseLevelList() async {
final List<Level> levelList = []; final List<Level> levelList = [];
levelList.add(Level( levelList.add(Level(
image: 'assets/images/jpg/level-1.jpg', image: 'assets/images/jpg/level-1.jpg',
@ -63,7 +63,7 @@ class LevelBoxRepositoryImpl extends LevelBoxRepository {
payable: true, payable: true,
)); ));
_levelBox.saveData(levelList); _levelBox.saveData(levelList);
result.call(levelList);
return levelList;
} }
@override @override
@ -80,4 +80,14 @@ class LevelBoxRepositoryImpl extends LevelBoxRepository {
Future<void> setCurrentLevel(int level) async { Future<void> setCurrentLevel(int level) async {
await _levelBox.setCurrentLevel(level); await _levelBox.setCurrentLevel(level);
} }
@override
Future<void> updateLevel(Level level) async {
await _levelBox.updateData(level: level);
}
@override
Future<List<Level>> getFilledLevelList() async {
return await _levelBox.getData();
}
} }

2
domain/repositories/android/local.properties

@ -0,0 +1,2 @@
sdk.dir=C:\\Work\\Tools\\Sdk
flutter.sdk=C:\\Work\\Tools\\flutter

14
domain/repositories/ios/Flutter/Generated.xcconfig

@ -0,0 +1,14 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=C:\Work\Tools\flutter
FLUTTER_APPLICATION_PATH=C:\Users\user1\StudioProjects\habib_kids\domain\repositories
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=lib\main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=0.0.1
FLUTTER_BUILD_NUMBER=0.0.1
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.dart_tool/package_config.json

13
domain/repositories/ios/Flutter/flutter_export_environment.sh

@ -0,0 +1,13 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=C:\Work\Tools\flutter"
export "FLUTTER_APPLICATION_PATH=C:\Users\user1\StudioProjects\habib_kids\domain\repositories"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib\main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=0.0.1"
export "FLUTTER_BUILD_NUMBER=0.0.1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"

2
domain/repositories/lib/level_box_domain/adapter/level_model_adapter.dart

@ -16,7 +16,7 @@ class LevelModelAdapter extends TypeAdapter<Level> {
puzzleSize: fields[1] as int, puzzleSize: fields[1] as int,
duration: fields[2] as int, duration: fields[2] as int,
level: fields[3] as int, level: fields[3] as int,
recordDuration: fields[4] as int,
recordDuration: fields[4] as String,
payable: fields[5] as bool, payable: fields[5] as bool,
); );
} }

15
domain/repositories/lib/level_box_domain/model/level_model.dart

@ -11,7 +11,7 @@ class Level extends HiveObject {
@HiveField(3) @HiveField(3)
final int level; final int level;
@HiveField(4) @HiveField(4)
final int recordDuration;
String recordDuration;
@HiveField(5) @HiveField(5)
final bool payable; final bool payable;
@ -20,7 +20,7 @@ class Level extends HiveObject {
required this.duration, required this.duration,
required this.puzzleSize, required this.puzzleSize,
required this.level, required this.level,
this.recordDuration = 0,
this.recordDuration = '',
this.payable = false, this.payable = false,
}); });
@ -34,4 +34,15 @@ class Level extends HiveObject {
'payable': payable, 'payable': payable,
}; };
} }
factory Level.fromJson(Map<String, dynamic> json) {
return Level(
image: json['image'],
duration: json['duration'],
puzzleSize: json['puzzleSize'],
level: json['level'],
recordDuration: json['recordDuration'],
payable: json['payable'],
);
}
} }

6
domain/repositories/lib/level_box_domain/repository/level_box_repository.dart

@ -1,11 +1,15 @@
import 'package:repositories/level_box_domain/model/level_model.dart'; import 'package:repositories/level_box_domain/model/level_model.dart';
abstract class LevelBoxRepository { abstract class LevelBoxRepository {
Future<void> getLevel({required void Function(List<Level> data) result});
Future<List<Level>> saveBaseLevelList();
Future<void> openBox(); Future<void> openBox();
Future<int> getCurrentLevel(); Future<int> getCurrentLevel();
Future<void> setCurrentLevel(int level); Future<void> setCurrentLevel(int level);
Future<void> updateLevel(Level level);
Future<List<Level>> getFilledLevelList();
} }

17
lib/cubits/count_down_timer_cubit.dart

@ -2,12 +2,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:my_flutter_puzzle/cubits/base_cubit_type.dart'; import 'package:my_flutter_puzzle/cubits/base_cubit_type.dart';
class CountDownTimerCubit extends Cubit<BaseCubitType<CountDownTimerState>> { class CountDownTimerCubit extends Cubit<BaseCubitType<CountDownTimerState>> {
CountDownTimerCubit()
: super(
BaseCubitType(
eventName: CountDownTimerState.empty,
),
);
Duration? _duration;
CountDownTimerCubit() : super(BaseCubitType(eventName: CountDownTimerState.empty));
void empty() => emit(BaseCubitType(eventName: CountDownTimerState.empty)); void empty() => emit(BaseCubitType(eventName: CountDownTimerState.empty));
@ -16,6 +13,14 @@ class CountDownTimerCubit extends Cubit<BaseCubitType<CountDownTimerState>> {
void stop() => emit(BaseCubitType(eventName: CountDownTimerState.stop)); void stop() => emit(BaseCubitType(eventName: CountDownTimerState.stop));
void reset() => emit(BaseCubitType(eventName: CountDownTimerState.reset)); void reset() => emit(BaseCubitType(eventName: CountDownTimerState.reset));
void setDuration(Duration duration) {
_duration = duration;
}
Duration? getDuration() {
return _duration;
}
} }
enum CountDownTimerState { enum CountDownTimerState {

1
lib/initializer.dart

@ -20,6 +20,5 @@ class Initializer {
Hive.init(dir.path); Hive.init(dir.path);
Hive.registerAdapter(LevelModelAdapter()); Hive.registerAdapter(LevelModelAdapter());
await _repository.openBox(); await _repository.openBox();
await _repository.setCurrentLevel(1);
} }
} }

34
lib/main.dart

@ -5,6 +5,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart'; import 'package:my_flutter_puzzle/cubits/count_down_timer_cubit.dart';
import 'package:my_flutter_puzzle/initializer.dart'; import 'package:my_flutter_puzzle/initializer.dart';
import 'package:my_flutter_puzzle/res/palette.dart'; import 'package:my_flutter_puzzle/res/palette.dart';
import 'package:my_flutter_puzzle/screens/level_list/cubit/level_list_cubit.dart';
import 'package:my_flutter_puzzle/screens/level_list/screen/level_list_screen.dart';
import 'package:my_flutter_puzzle/screens/splash/screen/splash_screen.dart'; import 'package:my_flutter_puzzle/screens/splash/screen/splash_screen.dart';
import 'package:my_flutter_puzzle/utils/color_brightness.dart'; import 'package:my_flutter_puzzle/utils/color_brightness.dart';
@ -24,30 +26,18 @@ class MyApp extends StatelessWidget {
DeviceOrientation.landscapeRight, DeviceOrientation.landscapeRight,
]); ]);
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
return BlocProvider(
create: (context) => CountDownTimerCubit(),
return MultiBlocProvider(
providers: [
BlocProvider<LevelListCubit>(create: (context) => LevelListCubit()),
BlocProvider<CountDownTimerCubit>(create: (context) => CountDownTimerCubit()),
],
child: MaterialApp( child: MaterialApp(
title: 'Flutter Puzzle',
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: 'GoogleSans',
backgroundColor: Palette.blue.darken(0.3),
colorScheme: ColorScheme(
brightness: Theme.of(context).brightness,
primary: Palette.blue,
onPrimary: Colors.white,
secondary: Palette.blue.withOpacity(0.6),
onSecondary: Palette.blue.withOpacity(0.3),
error: Theme.of(context).colorScheme.error,
onError: Theme.of(context).colorScheme.onError,
background: Palette.blue.darken(0.3),
onBackground: Colors.white,
surface: Palette.crimson,
onSurface: Colors.white38,
),
),
home: const SplashScreen(),
initialRoute: '/',
routes: {
'/': (context) => const SplashScreen(),
'level_list': (context) => const LevelListScreen(),
},
), ),
); );
} }

48
lib/screens/level_list/cubit/level_list_cubit.dart

@ -5,27 +5,55 @@ import 'package:repositories/level_box_domain/model/level_model.dart';
import 'package:repositories/level_box_domain/repository/level_box_repository.dart'; import 'package:repositories/level_box_domain/repository/level_box_repository.dart';
import 'package:types/level_data/interface/level_box_repository_impl.dart'; import 'package:types/level_data/interface/level_box_repository_impl.dart';
class LevelListCubit extends Cubit<BaseCubitType<LevelListCubitState>> {
class LevelListCubit extends Cubit<BaseCubitType<LevelListState>> {
List<Level> levelList = []; List<Level> levelList = [];
late int currentLevel; late int currentLevel;
final LevelBoxRepository _repository = LevelBoxRepositoryImpl(levelBox: LevelBox()); final LevelBoxRepository _repository = LevelBoxRepositoryImpl(levelBox: LevelBox());
LevelListCubit() : super(BaseCubitType(eventName: LevelListCubitState.empty));
LevelListCubit() : super(BaseCubitType(eventName: LevelListState.empty));
void empty() => emit(BaseCubitType(eventName: LevelListCubitState.empty));
void empty() => emit(BaseCubitType(eventName: LevelListState.empty));
void getData() async { void getData() async {
currentLevel = await _repository.getCurrentLevel(); currentLevel = await _repository.getCurrentLevel();
await _repository.getLevel(
result: (data) {
levelList = data;
emit(BaseCubitType(eventName: LevelListCubitState.list));
},
);
levelList = await _repository.getFilledLevelList();
if (levelList.isEmpty) {
levelList = await _repository.saveBaseLevelList();
} }
emit(BaseCubitType(eventName: LevelListState.list));
} }
enum LevelListCubitState {
Level getLevel() {
return levelList.firstWhere((element) => element.level == currentLevel);
}
void setRecordDuration(int level, Duration duration, Function callback) async {
int index = levelList.indexWhere((element) => element.level == level);
if (index == -1) {
return;
}
Level playedLevel = levelList[index];
if (playedLevel.recordDuration == '') {
playedLevel.recordDuration = _showDuration(duration, Duration(minutes: playedLevel.duration));
currentLevel += 1;
_repository.setCurrentLevel(currentLevel);
} else {
playedLevel.recordDuration = _showDuration(duration, Duration(minutes: playedLevel.duration));
}
await _repository.updateLevel(playedLevel);
callback.call();
}
String _showDuration(Duration duration, Duration baseDuration) {
final minutes = strDigits((baseDuration - duration).inMinutes.remainder(60));
final seconds = strDigits((baseDuration - duration).inSeconds.remainder(60));
return '$minutes:$seconds';
}
String strDigits(int n) => n.toString().padLeft(2, '0');
}
enum LevelListState {
empty, empty,
list, list,
} }

32
lib/screens/level_list/screen/level_list_screen.dart

@ -5,9 +5,7 @@ import 'package:my_flutter_puzzle/screens/level_list/cubit/level_list_cubit.dart
import 'package:my_flutter_puzzle/screens/level_list/widgets/level_widget.dart'; import 'package:my_flutter_puzzle/screens/level_list/widgets/level_widget.dart';
import 'package:my_flutter_puzzle/screens/level_list/widgets/lock_level_widget.dart'; import 'package:my_flutter_puzzle/screens/level_list/widgets/lock_level_widget.dart';
import 'package:my_flutter_puzzle/screens/level_list/widgets/payed_level_widget.dart'; import 'package:my_flutter_puzzle/screens/level_list/widgets/payed_level_widget.dart';
import 'package:my_flutter_puzzle/screens/lose/lose_screen.dart';
import 'package:my_flutter_puzzle/screens/puzzle/puzzle_starter_screen.dart'; import 'package:my_flutter_puzzle/screens/puzzle/puzzle_starter_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/context_extension.dart';
import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart'; import 'package:my_flutter_puzzle/utils/extensions/string_extensions.dart';
import 'package:repositories/level_box_domain/model/level_model.dart'; import 'package:repositories/level_box_domain/model/level_model.dart';
@ -20,12 +18,9 @@ class LevelListScreen extends StatefulWidget {
} }
class _LevelListScreenState extends State<LevelListScreen> { class _LevelListScreenState extends State<LevelListScreen> {
late final LevelListCubit _cubit;
@override @override
void initState() { void initState() {
_cubit = BlocProvider.of<LevelListCubit>(context);
_cubit.getData();
BlocProvider.of<LevelListCubit>(context).getData();
super.initState(); super.initState();
} }
@ -33,12 +28,12 @@ class _LevelListScreenState extends State<LevelListScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: const Color(0xff6236FF), backgroundColor: const Color(0xff6236FF),
body: BlocBuilder<LevelListCubit, BaseCubitType<LevelListCubitState>>(
body: BlocBuilder<LevelListCubit, BaseCubitType<LevelListState>>(
builder: (context, state) { builder: (context, state) {
switch (state.eventName!) { switch (state.eventName!) {
case LevelListCubitState.empty:
case LevelListState.empty:
break; break;
case LevelListCubitState.list:
case LevelListState.list:
break; break;
} }
return Padding( return Padding(
@ -73,18 +68,19 @@ class _LevelListScreenState extends State<LevelListScreen> {
height: context.height * 397 / 540, height: context.height * 397 / 540,
child: ListView.builder( child: ListView.builder(
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (_cubit.levelList[index].level == _cubit.currentLevel) {
if (BlocProvider.of<LevelListCubit>(context).levelList[index].level <=
BlocProvider.of<LevelListCubit>(context).currentLevel) {
return GestureDetector( return GestureDetector(
onTap: () => _startLevel(_cubit.levelList[index]),
child: LevelWidget(level: _cubit.levelList[index]),
onTap: () => _startLevel(BlocProvider.of<LevelListCubit>(context).levelList[index]),
child: LevelWidget(level: BlocProvider.of<LevelListCubit>(context).levelList[index]),
); );
} }
if (_cubit.levelList[index].payable) {
return PayedLevelWidget(level: _cubit.levelList[index]);
if (BlocProvider.of<LevelListCubit>(context).levelList[index].payable) {
return PayedLevelWidget(level: BlocProvider.of<LevelListCubit>(context).levelList[index]);
} }
return LockLevelWidget(level: _cubit.levelList[index]);
return LockLevelWidget(level: BlocProvider.of<LevelListCubit>(context).levelList[index]);
}, },
itemCount: _cubit.levelList.length,
itemCount: BlocProvider.of<LevelListCubit>(context).levelList.length,
), ),
), ),
], ],
@ -110,6 +106,8 @@ class _LevelListScreenState extends State<LevelListScreen> {
); );
}, },
), ),
);
).then((value) {
BlocProvider.of<LevelListCubit>(context).getData();
});
} }
} }

5
lib/screens/lose/lose_screen.dart

@ -141,6 +141,10 @@ class _LoseScreenState extends State<LoseScreen> {
), ),
Transform.translate( Transform.translate(
offset: const Offset(0, 20), offset: const Offset(0, 20),
child: GestureDetector(
onTap: () {
Navigator.pop(context, true);
},
child: Container( child: Container(
width: context.width * 147 / 812, width: context.width * 147 / 812,
height: context.height * 51 / 375, height: context.height * 51 / 375,
@ -202,6 +206,7 @@ class _LoseScreenState extends State<LoseScreen> {
), ),
), ),
), ),
),
], ],
), ),
), ),

9
lib/screens/photo/photo_screen.dart

@ -52,8 +52,7 @@ class _PhotoScreenState extends ConsumerState<PhotoScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ref.listen(puzzleNotifierProvider(_solverClient),
(previous, PuzzleState next) {
ref.listen(puzzleNotifierProvider(_solverClient), (previous, PuzzleState next) {
if (next is PuzzleSolved) { if (next is PuzzleSolved) {
BlocProvider.of<CountDownTimerCubit>(context).stop(); BlocProvider.of<CountDownTimerCubit>(context).stop();
} }
@ -70,8 +69,7 @@ class _PhotoScreenState extends ConsumerState<PhotoScreen> {
onSecondary: Theme.of(context).colorScheme.onSecondary, onSecondary: Theme.of(context).colorScheme.onSecondary,
error: Theme.of(context).colorScheme.error, error: Theme.of(context).colorScheme.error,
onError: Theme.of(context).colorScheme.onError, onError: Theme.of(context).colorScheme.onError,
background:
next.palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
background: next.palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
onBackground: Colors.white, onBackground: Colors.white,
surface: Theme.of(context).colorScheme.surface, surface: Theme.of(context).colorScheme.surface,
onSurface: Theme.of(context).colorScheme.onSurface, onSurface: Theme.of(context).colorScheme.onSurface,
@ -110,8 +108,7 @@ class _PhotoScreenState extends ConsumerState<PhotoScreen> {
onSecondary: Theme.of(context).colorScheme.onSecondary, onSecondary: Theme.of(context).colorScheme.onSecondary,
error: Theme.of(context).colorScheme.error, error: Theme.of(context).colorScheme.error,
onError: Theme.of(context).colorScheme.onError, onError: Theme.of(context).colorScheme.onError,
background:
palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
background: palette.darkMutedColor?.color ?? Palette.blue.darken(0.3),
onBackground: Colors.white, onBackground: Colors.white,
surface: Theme.of(context).colorScheme.surface, surface: Theme.of(context).colorScheme.surface,
onSurface: Theme.of(context).colorScheme.onSurface, onSurface: Theme.of(context).colorScheme.onSurface,

46
lib/screens/photo/photo_screen_large.dart

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -8,12 +10,12 @@ 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/models/puzzle_data.dart';
import 'package:my_flutter_puzzle/providers.dart'; import 'package:my_flutter_puzzle/providers.dart';
import 'package:my_flutter_puzzle/res/puzzle_constants.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/lose/lose_screen.dart';
import 'package:my_flutter_puzzle/screens/win/win_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/context_extension.dart';
import 'package:my_flutter_puzzle/utils/extensions/string_extensions.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/utils/puzzle_solver.dart';
import 'package:my_flutter_puzzle/utils/utils.dart';
import 'package:my_flutter_puzzle/widgets/photo_screen/image_viewer.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/count_down_timer_widget.dart';
import 'package:my_flutter_puzzle/widgets/solo_screen/countdown_widget.dart'; import 'package:my_flutter_puzzle/widgets/solo_screen/countdown_widget.dart';
@ -68,6 +70,30 @@ class _SoloScreenLargeState extends ConsumerState<PhotoScreenLarge> {
_eachBoxSize = (_boardSize / _puzzleSize) - (_spacing * (_puzzleSize - 1)); _eachBoxSize = (_boardSize / _puzzleSize) - (_spacing * (_puzzleSize - 1));
_initialPuzzleData = widget.initialPuzzleData; _initialPuzzleData = widget.initialPuzzleData;
_riveController = widget.riveController; _riveController = widget.riveController;
Timer timer = Timer(
const Duration(seconds: 10),
() {
_puzzleSolved = true;
BlocProvider.of<CountDownTimerCubit>(context).stop();
BlocProvider.of<LevelListCubit>(context).setRecordDuration(
widget.level,
BlocProvider.of<CountDownTimerCubit>(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,
);
},
));
});
},
);
},
);
super.initState(); super.initState();
} }
@ -81,8 +107,13 @@ class _SoloScreenLargeState extends ConsumerState<PhotoScreenLarge> {
} }
if (next is PuzzleSolved) { if (next is PuzzleSolved) {
_puzzleSolved = true; _puzzleSolved = true;
BlocProvider.of<CountDownTimerCubit>(context).stop();
BlocProvider.of<LevelListCubit>(context).setRecordDuration(
widget.level,
BlocProvider.of<CountDownTimerCubit>(context).getDuration() ?? Duration(minutes: widget.duration),
() {
Future.delayed(const Duration(milliseconds: 500), () { Future.delayed(const Duration(milliseconds: 500), () {
Navigator.push(context, MaterialPageRoute(
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (context) { builder: (context) {
return WinScreen( return WinScreen(
tiles: _tiles, tiles: _tiles,
@ -92,6 +123,8 @@ class _SoloScreenLargeState extends ConsumerState<PhotoScreenLarge> {
}, },
)); ));
}); });
},
);
} }
}); });
@ -280,7 +313,14 @@ class _SoloScreenLargeState extends ConsumerState<PhotoScreenLarge> {
builder: (context) { builder: (context) {
return LoseScreen(tiles: _tiles, move: _moves); return LoseScreen(tiles: _tiles, move: _moves);
}, },
));
)).then((value) {
if (value == true) {
BlocProvider.of<CountDownTimerCubit>(context).reset();
BlocProvider.of<CountDownTimerCubit>(context).start();
} else {
Navigator.pop(context);
}
});
}); });
} }
} }

5
lib/screens/splash/screen/splash_screen.dart

@ -19,10 +19,7 @@ class _SplashScreenState extends State<SplashScreen> {
Timer(const Duration(milliseconds: 2000), () { Timer(const Duration(milliseconds: 2000), () {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
builder: (context) { builder: (context) {
return BlocProvider(
child: const LevelListScreen(),
create: (context) => LevelListCubit(),
);
return const LevelListScreen();
}, },
)); ));
}); });

31
lib/screens/win/win_screen.dart

@ -1,7 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:my_flutter_puzzle/screens/level_list/cubit/level_list_cubit.dart';
import 'package:my_flutter_puzzle/screens/puzzle/puzzle_starter_screen.dart';
import 'package:my_flutter_puzzle/utils/extensions/context_extension.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/extensions/string_extensions.dart';
import 'package:repositories/level_box_domain/model/level_model.dart';
class WinScreen extends StatefulWidget { class WinScreen extends StatefulWidget {
final int move; final int move;
@ -151,9 +155,7 @@ class _WinScreenState extends State<WinScreen> {
Transform.translate( Transform.translate(
offset: const Offset(0, 20), offset: const Offset(0, 20),
child: GestureDetector( child: GestureDetector(
onTap: () {
},
onTap: _openNextLevel,
child: Container( child: Container(
width: context.width * 160 / 812, width: context.width * 160 / 812,
height: context.height * 51 / 375, height: context.height * 51 / 375,
@ -232,4 +234,27 @@ class _WinScreenState extends State<WinScreen> {
), ),
); );
} }
void _openNextLevel() {
int currentLevel = BlocProvider.of<LevelListCubit>(context).currentLevel;
if (currentLevel == 8) {
// all levels are done
Navigator.popUntil(context, ModalRoute.withName('/'));
} else {
Level level = BlocProvider.of<LevelListCubit>(context).getLevel();
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) {
return PuzzleStarterScreen(
duration: level.duration,
puzzleSize: level.puzzleSize,
image: level.image,
level: level.level,
);
},
),
);
}
}
} }

80
lib/widgets/solo_screen/count_down_timer_widget.dart

@ -19,53 +19,21 @@ class CountDownTimerWidget extends StatefulWidget {
class _CountDownTimerWidgetState extends State<CountDownTimerWidget> { class _CountDownTimerWidgetState extends State<CountDownTimerWidget> {
Timer? _countdownTimer; Timer? _countdownTimer;
Duration? myDuration;
Duration? _duration;
late final CountDownTimerCubit _cubit; late final CountDownTimerCubit _cubit;
@override @override
void initState() { void initState() {
_cubit = BlocProvider.of<CountDownTimerCubit>(context); _cubit = BlocProvider.of<CountDownTimerCubit>(context);
myDuration = Duration(minutes: widget.duration);
_duration = Duration(minutes: widget.duration);
super.initState(); super.initState();
} }
void startTimer() {
myDuration = Duration(minutes: widget.duration);
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (_) => setCountDown());
}
void stopTimer() {
if (_countdownTimer == null) {
return;
}
setState(() => _countdownTimer!.cancel());
}
void resetTimer() {
stopTimer();
setState(() => myDuration = Duration(minutes: widget.duration));
startTimer();
}
void setCountDown() {
const reduceSecondsBy = 1;
setState(() {
final seconds = myDuration!.inSeconds - reduceSecondsBy;
if (seconds < 0) {
widget.finishCallback.call();
_countdownTimer!.cancel();
} else {
myDuration = Duration(seconds: seconds);
}
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
String strDigits(int n) => n.toString().padLeft(2, '0'); String strDigits(int n) => n.toString().padLeft(2, '0');
final hours = strDigits(myDuration!.inHours.remainder(24));
final minutes = strDigits(myDuration!.inMinutes.remainder(60));
final seconds = strDigits(myDuration!.inSeconds.remainder(60));
final minutes = strDigits(_duration!.inMinutes.remainder(60));
final seconds = strDigits(_duration!.inSeconds.remainder(60));
return BlocBuilder<CountDownTimerCubit, BaseCubitType<CountDownTimerState>>( return BlocBuilder<CountDownTimerCubit, BaseCubitType<CountDownTimerState>>(
builder: (context, state) { builder: (context, state) {
switch (state.eventName!) { switch (state.eventName!) {
@ -73,19 +41,19 @@ class _CountDownTimerWidgetState extends State<CountDownTimerWidget> {
break; break;
case CountDownTimerState.start: case CountDownTimerState.start:
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
startTimer();
_startTimer();
_cubit.empty(); _cubit.empty();
}); });
break; break;
case CountDownTimerState.stop: case CountDownTimerState.stop:
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
stopTimer();
_stopTimer();
_cubit.empty(); _cubit.empty();
}); });
break; break;
case CountDownTimerState.reset: case CountDownTimerState.reset:
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
resetTimer();
_resetTimer();
_cubit.empty(); _cubit.empty();
}); });
break; break;
@ -93,7 +61,7 @@ class _CountDownTimerWidgetState extends State<CountDownTimerWidget> {
return Row( return Row(
children: [ children: [
Text( Text(
'$hours:$minutes:$seconds',
'$minutes:$seconds',
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -107,4 +75,36 @@ class _CountDownTimerWidgetState extends State<CountDownTimerWidget> {
}, },
); );
} }
void _startTimer() {
_duration = Duration(minutes: widget.duration);
_countdownTimer = Timer.periodic(const Duration(seconds: 1), (_) => _setCountDown());
}
void _stopTimer() {
if (_countdownTimer == null) {
return;
}
setState(() => _countdownTimer!.cancel());
}
void _resetTimer() {
_stopTimer();
setState(() => _duration = Duration(minutes: widget.duration));
_startTimer();
}
void _setCountDown() {
const reduceSecondsBy = 1;
setState(() {
final seconds = _duration!.inSeconds - reduceSecondsBy;
if (seconds < 0) {
widget.finishCallback.call();
_countdownTimer!.cancel();
} else {
_duration = Duration(seconds: seconds);
_cubit.setDuration(_duration!);
}
});
}
} }

2
lib/widgets/solo_screen/moves_tiles_widget/moves_tiles_text.dart

@ -88,7 +88,7 @@ class MovesTilesText extends StatelessWidget {
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 12,
fontSize: 10,
), ),
), ),
], ],

Loading…
Cancel
Save