diff --git a/README.md b/README.md index fcf28be..da877a8 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,62 @@ # Xpeho FlutterPuzzleHack -This project contains the FlutterPuzzleHack Xpeho participation sources +![Photo Booth Header][logo] -## Getting Started With Flutter +A slide puzzle built for [Flutter Challenge](https://flutterhack.devpost.com/). -This project is a starting point for a Flutter application. +*Built by [XPEHO][xpeho_link].* -A few resources to get you started if this is your first Flutter project: -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) +--- -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +## Getting Started 🚀 -## macOS arm64 Build (M1 chip) +To run the project either use the launch configuration in VSCode/Android Studio/IntelliJ or use the following command: -If you use a MacOS machine, you can build the app for arm64 using the following command: +```sh +$ flutter run -d chrome +``` + +--- + + +## Working with Translations 🌐 + +This project relies on [flutter_localizations][flutter_localizations_link] and follows the [official internationalization guide for Flutter][internationalization_link]. + +### Adding Strings -```bash -$ sudo arch -x86_64 gem install ffi -$ cd macos # or ios -$ arch -x86_64 pod install -$ cd .. -$ flutter build macos --debug # or flutter run -d macos +To add a new localizable string, open the `app_en.arb` file at `lib/l10n/arb/app_en.arb`. + +```arb +{ + "team_name": "Xpeho mobile", + "@team_name": { + "description": "Team name" + } +} ``` -This commands will build the macOS app for x86_64 architecture and will run the app using Rosetta. +--- + +## XPEHO FlutterPuzzleHack Cross Platform ⌚️💻📱 + +Available platforms : + +- [Web][pwa_link] +- IOS +- Android +- MacOS +- Windows + +Coming soon Linux and ... WatchOS + -## Windows Build +--- -In order to build this app for Windows you must previously install Visual Studio 2022. -More details [here](https://docs.flutter.dev/desktop#additional-windows-requirements) \ No newline at end of file +[logo]: assets/images/header_readme.png +[xpeho_link]: https://xpeho.fr/ +[flutter_localizations_link]: https://api.flutter.dev/flutter/flutter_localizations/flutter_localizations-library.html +[internationalization_link]: https://flutter.dev/docs/development/accessibility-and-localization/internationalization +[pwa_link]: https://xpeho-flutter-puzzle-hack.web.app/ diff --git a/assets/images/header_readme.png b/assets/images/header_readme.png new file mode 100644 index 0000000..f787ee7 Binary files /dev/null and b/assets/images/header_readme.png differ diff --git a/lib/bloc/puzzle_state.dart b/lib/bloc/puzzle_state.dart index ae7de68..a3ae98f 100644 --- a/lib/bloc/puzzle_state.dart +++ b/lib/bloc/puzzle_state.dart @@ -5,6 +5,7 @@ import 'package:puzzle/models/models.dart'; part 'puzzle_state.freezed.dart'; +///State management for the puzzle @freezed class PuzzleState with _$PuzzleState { factory PuzzleState( diff --git a/lib/models/puzzle.dart b/lib/models/puzzle.dart index 344440f..ea6c565 100644 --- a/lib/models/puzzle.dart +++ b/lib/models/puzzle.dart @@ -1,5 +1,8 @@ import 'package:puzzle/models/models.dart'; +/// Class Puzzle +/// Complexity management +/// List Tile management class Puzzle { final int complexity; final List data; @@ -9,6 +12,7 @@ class Puzzle { required this.data, }); + /// Generate value for the puzzle factory Puzzle.generate(int complexity) { final data = List.generate(complexity * complexity, (index) { var value = index + 1; @@ -64,6 +68,7 @@ class Puzzle { ); } + /// Check if move left is possible bool canSwapLeft() { final int emptyIndex = data.indexOf(data.firstWhere((tile) => tile.value == 0)); @@ -71,6 +76,7 @@ class Puzzle { return (emptyIndex == 0 || (emptyIndex + 1) % complexity != 0); } + /// try to swap empty tile and the one on the right Puzzle trySwapLeft() { final int emptyIndex = data.indexOf(data.firstWhere((tile) => tile.value == 0)); @@ -84,6 +90,7 @@ class Puzzle { return move(data[valueIndex].value); } + /// Check if move right is possible bool canSwapRight() { final int emptyIndex = data.indexOf(data.firstWhere((tile) => tile.value == 0)); @@ -105,6 +112,7 @@ class Puzzle { return move(data[valueIndex].value); } + /// Check if move in up is possible bool canSwapUp() { final int emptyIndex = data.indexOf(data.firstWhere((tile) => tile.value == 0)); @@ -128,6 +136,7 @@ class Puzzle { return move(data[valueIndex].value); } + /// Check if move in down is possible bool canSwapDown() { final int emptyIndex = data.indexOf(data.firstWhere((tile) => tile.value == 0)); @@ -151,6 +160,7 @@ class Puzzle { return move(data[valueIndex].value); } + /// Check if move is possible bool canSwap(int value) { final int emptyIndex = values.indexOf(0); diff --git a/lib/models/tile.dart b/lib/models/tile.dart index 007fad8..756be18 100644 --- a/lib/models/tile.dart +++ b/lib/models/tile.dart @@ -1,3 +1,6 @@ +/// Class Tile +/// Differents position X & Y +/// The value for different tile class Tile { int targetX; int targetY; diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart index d00de00..6098758 100644 --- a/lib/services/audio_service.dart +++ b/lib/services/audio_service.dart @@ -3,6 +3,10 @@ import 'package:flutter/foundation.dart'; import 'package:puzzle/services/shared.dart'; import 'package:volume_controller/volume_controller.dart'; +/// Class AudioService for audio player in the app +/// Cache management +/// Volume management +/// Audio player management class AudioService { final AudioPlayer _audioPlayer = AudioPlayer(); final AudioCache _audioCache = AudioCache(); diff --git a/lib/services/shared.dart b/lib/services/shared.dart index 0feb032..85106b3 100644 --- a/lib/services/shared.dart +++ b/lib/services/shared.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; +// This file is for method in general +/// Method for detection if we are in mobile or web bool isMobile() { if (kIsWeb) { return false; diff --git a/lib/view/puzzle_page/puzzle_page.dart b/lib/view/puzzle_page/puzzle_page.dart index f3a0e37..e351591 100644 --- a/lib/view/puzzle_page/puzzle_page.dart +++ b/lib/view/puzzle_page/puzzle_page.dart @@ -32,6 +32,7 @@ class _PuzzlePageState extends State { void initState() { super.initState(); _puzzleFocusNode = FocusNode(); + //Shake animations : start shuffle function detector = ShakeDetector.autoStart(onPhoneShake: () { _shuffle(context); }); @@ -113,16 +114,19 @@ class _PuzzlePageState extends State { _puzzleFocusNode.requestFocus(); } + /// Up complexity of puzzle : Number of tile void _increaseComplexity(BuildContext context) { context.read().increaseComplexity(); _puzzleFocusNode.requestFocus(); } + /// Decrease complexity of puzzle : Number of tile void _decreaseComplexity(BuildContext context) { context.read().decreaseComplexity(); _puzzleFocusNode.requestFocus(); } + /// Load picture for the puzzle Future _pickImage() async { FilePickerResult? result = await FilePicker.platform.pickFiles(); @@ -137,6 +141,7 @@ class _PuzzlePageState extends State { } } + /// Build the portrait mode Widget _buildPortrait(BuildContext context, PuzzleState state) { return Scaffold( bottomNavigationBar: Padding( @@ -203,6 +208,7 @@ class _PuzzlePageState extends State { ); } + /// Build the landscape mode Widget _buildLandscape(BuildContext context, PuzzleState state) { return Scaffold( body: Column(