├── .firebaserc
├── .git-hooks
├── pre-commit
└── pre-push
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── config.yml
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── check.yml
│ └── deploy_web.yml
├── .gitignore
├── .idea
└── runConfigurations
│ ├── development.xml
│ ├── production.xml
│ └── staging.xml
├── .metadata
├── .vscode
├── extensions.json
├── launch.json
└── tasks.json
├── LICENSE
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── apparence
│ │ │ │ └── flutter_puzzle_hack
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── animations
│ └── apparence.riv
├── images
│ ├── 2.0x
│ │ └── flutter_logo.png
│ ├── 3.0x
│ │ └── flutter_logo.png
│ ├── background.jpg
│ ├── buttons
│ │ ├── button.png
│ │ ├── button_hover.png
│ │ ├── button_music_off.png
│ │ ├── button_music_on.png
│ │ ├── button_play_again_hover.png
│ │ ├── button_sound_off.png
│ │ └── button_sound_on.png
│ ├── flutter_logo.png
│ ├── glouglou.png
│ ├── logos.png
│ └── timer_icon.png
└── themes
│ └── base
│ ├── audio
│ ├── music.mp3
│ └── pop.wav
│ ├── tile_cross.riv
│ ├── tile_end.riv
│ ├── tile_horizontal.riv
│ ├── tile_left_bottom.riv
│ ├── tile_left_top.riv
│ ├── tile_right_bottom.riv
│ ├── tile_start.riv
│ ├── tile_top_right.riv
│ └── tile_vertical.riv
├── base_analysis_options.yaml
├── coverage_badge.svg
├── firebase.json
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── Runner.xcscheme
│ │ ├── development.xcscheme
│ │ ├── production.xcscheme
│ │ └── staging.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── l10n.yaml
├── lib
├── boostrap.dart
├── main.dart
├── main_development.dart
├── main_staging.dart
└── src
│ ├── app.dart
│ ├── l10n
│ ├── arb
│ │ ├── app_en.arb
│ │ └── app_fr.arb
│ └── l10n.dart
│ ├── layout
│ ├── breakpoint_provider.dart
│ └── responsive_layout_builder.dart
│ ├── models
│ ├── connection.dart
│ ├── dimension.dart
│ ├── position.dart
│ ├── puzzle.dart
│ ├── ticker.dart
│ └── tile.dart
│ ├── puzzle
│ ├── audio_controller
│ │ └── audio_controller.dart
│ ├── helpers
│ │ ├── audio_player.dart
│ │ └── puzzle_generator.dart
│ ├── view
│ │ └── puzzle_page.dart
│ └── widgets
│ │ ├── puzzle_board.dart
│ │ ├── puzzle_move_counter.dart
│ │ ├── puzzle_tile.dart
│ │ ├── puzzle_timer.dart
│ │ ├── puzzle_victory_dialog.dart
│ │ └── scale_up_animation.dart
│ ├── splashscreen
│ └── splashscreen.dart
│ └── theme
│ └── app_theme.dart
├── linux
├── .gitignore
├── CMakeLists.txt
├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
├── main.cc
├── my_application.cc
└── my_application.h
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── app_icon_1024.png
│ │ ├── app_icon_128.png
│ │ ├── app_icon_16.png
│ │ ├── app_icon_256.png
│ │ ├── app_icon_32.png
│ │ ├── app_icon_512.png
│ │ └── app_icon_64.png
│ ├── Base.lproj
│ └── MainMenu.xib
│ ├── Configs
│ ├── AppInfo.xcconfig
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── Warnings.xcconfig
│ ├── DebugProfile.entitlements
│ ├── Info.plist
│ ├── MainFlutterWindow.swift
│ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── readme-doc
├── logos.png
└── showcase-readme.jpg
├── scripts
└── coverage.sh
├── test
├── helpers
│ ├── helpers.dart
│ ├── pump_app.dart
│ └── set_display_size.dart
├── layout
│ ├── breakpoint_provider_test.dart
│ └── responsive_layout_builder_test.dart
├── models
│ ├── connection_test.dart
│ ├── dimension_test.dart
│ ├── position_test.dart
│ ├── puzzle_test.dart
│ ├── ticker_test.dart
│ └── tile_test.dart
├── unit_test.dart
└── widget_test.dart
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── index.html
└── manifest.json
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
├── CMakeLists.txt
├── generated_plugin_registrant.cc
├── generated_plugin_registrant.h
└── generated_plugins.cmake
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "projects": {
3 | "default": "apparence-flutter-puzzle"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.git-hooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Setup: git config core.hooksPath .git-hooks
4 |
5 | # Stash unstaged changes
6 | git stash -q --keep-index
7 |
8 | # Run Flutter analyzer
9 | printf "\e[33;1m%s\e[0m\n" 'Running the Flutter analyzer'
10 | flutter analyze
11 | if [ $? -ne 0 ]; then
12 | printf "\e[31;1m%s\e[0m\n" 'Flutter analyzer error'
13 | exit 1
14 | fi
15 | printf "\e[33;1m%s\e[0m\n" 'Finished running the Flutter analyzer'
16 |
17 | # Run tests
18 | printf "\e[33;1m%s\e[0m\n" 'Running tests'
19 | flutter test
20 | if [ $? -ne 0 ]; then
21 | printf "\e[31;1m%s\e[0m\n" 'Tests error'
22 | exit 1
23 | fi
24 | printf "\e[33;1m%s\e[0m\n" 'Finished running tests'
25 |
26 | # Run Flutter formatter
27 | printf "\e[33;1m%s\e[0m\n" 'Running the Flutter formatter'
28 | flutter format .
29 | printf "\e[33;1m%s\e[0m\n" 'Finished running the Flutter formatter'
30 |
31 | # Stage updated files
32 | git add -u
33 |
34 | # Re-apply original unstaged changes
35 | git stash pop -q
36 |
--------------------------------------------------------------------------------
/.git-hooks/pre-push:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Setup: git config core.hooksPath .git-hooks
4 |
5 | # Run Flutter analyzer
6 | printf "\e[33;1m%s\e[0m\n" 'Running the Flutter analyzer'
7 | flutter analyze
8 | if [ $? -ne 0 ]; then
9 | printf "\e[31;1m%s\e[0m\n" 'Flutter analyzer error'
10 | exit 1
11 | fi
12 | printf "\e[33;1m%s\e[0m\n" 'Finished running the Flutter analyzer'
13 |
14 | # Run tests
15 | printf "\e[33;1m%s\e[0m\n" 'Running tests'
16 | flutter test
17 | if [ $? -ne 0 ]; then
18 | printf "\e[31;1m%s\e[0m\n" 'Tests error'
19 | exit 1
20 | fi
21 | printf "\e[33;1m%s\e[0m\n" 'Finished running tests'
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Create a report to help us improve
4 | title: "fix: "
5 | labels: bug
6 | ---
7 |
8 | **Description**
9 | A clear and concise description of what the bug is.
10 |
11 | **Steps To Reproduce**
12 |
13 | 1. Go to '...'
14 | 2. Click on '....'
15 | 3. Scroll down to '....'
16 | 4. See error
17 |
18 | **Expected Behavior**
19 | A clear and concise description of what you expected to happen.
20 |
21 | **Screenshots**
22 | If applicable, add screenshots to help explain your problem.
23 |
24 | **Additional Context**
25 | Add any other context about the problem here.
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
8 |
9 | ## Description
10 |
11 |
12 |
13 | ## Type of Change
14 |
15 |
16 |
17 | - [ ] ✨ New feature (non-breaking change which adds functionality)
18 | - [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
19 | - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change)
20 | - [ ] 🧹 Code refactor
21 | - [ ] ✅ Build configuration change
22 | - [ ] 📝 Documentation
23 | - [ ] 🗑️ Chore
24 |
--------------------------------------------------------------------------------
/.github/workflows/check.yml:
--------------------------------------------------------------------------------
1 | name: Application Check
2 |
3 | on:
4 | pull_request:
5 | push:
6 | paths:
7 | - "lib/**"
8 | - "test/**"
9 | - "pubspec.yaml"
10 | - "pubspec.lock"
11 | - ".github/workflows/check.yml"
12 | branches-ignore:
13 | - main
14 |
15 | jobs:
16 | check:
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - uses: actions/checkout@v2
21 |
22 | - uses: subosito/flutter-action@v2
23 | with:
24 | flutter-version: 2.8.1
25 | channel: stable
26 | cache: true
27 |
28 | - name: Install Dependencies
29 | run: flutter packages get
30 |
31 | - name: Format
32 | run: flutter format --set-exit-if-changed lib test
33 |
34 | - name: Analyze
35 | run: flutter analyze lib test
36 |
37 | - name: Run tests
38 | run: flutter test --no-pub --coverage --test-randomize-ordering-seed random
39 |
40 |
--------------------------------------------------------------------------------
/.github/workflows/deploy_web.yml:
--------------------------------------------------------------------------------
1 | name: Web Deployment
2 |
3 | on:
4 | push:
5 | paths:
6 | - "lib/**"
7 | - "pubspec.yaml"
8 | - "pubspec.lock"
9 | - ".github/workflows/deploy_web.yml"
10 | branches:
11 | - main
12 |
13 | jobs:
14 | deploy:
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 |
20 | - uses: subosito/flutter-action@v2
21 | with:
22 | flutter-version: 2.8.1
23 | channel: stable
24 | cache: true
25 |
26 | - name: Install Dependencies
27 | run: flutter packages get
28 |
29 | - name: Format
30 | run: flutter format --set-exit-if-changed lib test
31 |
32 | - name: Analyze
33 | run: flutter analyze lib test
34 |
35 | - name: Run tests
36 | run: flutter test --no-pub --coverage --test-randomize-ordering-seed random
37 |
38 | - name: Build web version
39 | run: flutter build web
40 |
41 | - name: Deploy on Firebase
42 | uses: FirebaseExtended/action-hosting-deploy@v0
43 | with:
44 | repoToken: "${{ secrets.GITHUB_TOKEN }}"
45 | firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT }}"
46 | projectId: apparence-flutter-puzzle
47 | target: apparence-flutter-puzzle
48 | expires: 30d
49 | channelId: live
50 |
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/*
18 |
19 | # Visual Studio Code related
20 | .classpath
21 | .project
22 | .settings/
23 | .vscode/*
24 |
25 | # Flutter repo-specific
26 | /bin/cache/
27 | /bin/mingit/
28 | /dev/benchmarks/mega_gallery/
29 | /dev/bots/.recipe_deps
30 | /dev/bots/android_tools/
31 | /dev/docs/doc/
32 | /dev/docs/flutter.docs.zip
33 | /dev/docs/lib/
34 | /dev/docs/pubspec.yaml
35 | /dev/integration_tests/**/xcuserdata
36 | /dev/integration_tests/**/Pods
37 | /packages/flutter/coverage/
38 | version
39 |
40 | # packages file containing multi-root paths
41 | .packages.generated
42 |
43 | # Flutter/Dart/Pub related
44 | **/doc/api/
45 | **/ios/Flutter/.last_build_id
46 | .dart_tool/
47 | .flutter-plugins
48 | .flutter-plugins-dependencies
49 | .packages
50 | .pub-cache/
51 | .pub/
52 | build/
53 | linked_*.ds
54 | unlinked.ds
55 | unlinked_spec.ds
56 | .fvm/
57 |
58 | # Android related
59 | **/android/**/gradle-wrapper.jar
60 | **/android/.gradle
61 | **/android/captures/
62 | **/android/gradlew
63 | **/android/gradlew.bat
64 | **/android/local.properties
65 | **/android/**/GeneratedPluginRegistrant.java
66 | **/android/key.properties
67 | **/android/.idea/
68 | *.jks
69 |
70 | # iOS/XCode related
71 | **/ios/**/*.mode1v3
72 | **/ios/**/*.mode2v3
73 | **/ios/**/*.moved-aside
74 | **/ios/**/*.pbxuser
75 | **/ios/**/*.perspectivev3
76 | **/ios/**/*sync/
77 | **/ios/**/.sconsign.dblite
78 | **/ios/**/.tags*
79 | **/ios/**/.vagrant/
80 | **/ios/**/DerivedData/
81 | **/ios/**/Icon?
82 | **/ios/**/Pods/
83 | **/ios/**/.symlinks/
84 | **/ios/**/profile
85 | **/ios/**/xcuserdata
86 | **/ios/.generated/
87 | **/ios/Flutter/App.framework
88 | **/ios/Flutter/Flutter.framework
89 | **/ios/Flutter/Flutter.podspec
90 | **/ios/Flutter/Generated.xcconfig
91 | **/ios/Flutter/app.flx
92 | **/ios/Flutter/app.zip
93 | **/ios/Flutter/.last_build_id
94 | **/ios/Flutter/flutter_assets/
95 | **/ios/Flutter/flutter_export_environment.sh
96 | **/ios/ServiceDefinitions.json
97 | **/ios/Runner/GeneratedPluginRegistrant.*
98 |
99 | # Coverage
100 | coverage/
101 |
102 | # Submodules
103 | !pubspec.lock
104 | packages/**/pubspec.lock
105 |
106 | # Web related
107 | lib/generated_plugin_registrant.dart
108 |
109 | # Symbolication related
110 | app.*.symbols
111 |
112 | # Obfuscation related
113 | app.*.map.json
114 |
115 | # Exceptions to the above rules.
116 | !**/ios/**/default.mode1v3
117 | !**/ios/**/default.mode2v3
118 | !**/ios/**/default.pbxuser
119 | !**/ios/**/default.perspectivev3
120 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
121 | !/dev/ci/**/Gemfile.lock
122 | !.vscode/extensions.json
123 | !.vscode/launch.json
124 | !.vscode/tasks.json
125 | !.idea/codeStyles/
126 | !.idea/dictionaries/
127 | !.idea/runConfigurations/
128 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/development.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/production.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/staging.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 77d935af4db863f6abd0b9c31c7e6df2a13de57b
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": [
5 | "dart-code.dart-code",
6 | "dart-code.flutter",
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Tests",
6 | "request": "launch",
7 | "type": "dart",
8 | "presentation": {
9 | "group": "test"
10 | },
11 | "program": "test",
12 | "args": ["--coverage", "--test-randomize-ordering-seed", "random"]
13 | },
14 | {
15 | "name": "Development",
16 | "request": "launch",
17 | "type": "dart",
18 | "presentation": {
19 | "group": "launch"
20 | },
21 | "program": "lib/main_development.dart",
22 | "args": [
23 | "--flavor",
24 | "development",
25 | "--target",
26 | "lib/main_development.dart"
27 | ]
28 | },
29 | {
30 | "name": "Development & profile",
31 | "request": "launch",
32 | "type": "dart",
33 | "flutterMode": "profile",
34 | "showMemoryUsage": true,
35 | "openDevTools": "logging",
36 | "presentation": {
37 | "group": "launch"
38 | },
39 | "program": "lib/main_development.dart",
40 | "args": [
41 | "--flavor",
42 | "development",
43 | "--target",
44 | "lib/main_development.dart"
45 | ]
46 | },
47 | {
48 | "name": "Staging",
49 | "request": "launch",
50 | "type": "dart",
51 | "presentation": {
52 | "group": "launch"
53 | },
54 | "program": "lib/main_staging.dart",
55 | "args": ["--flavor", "staging", "--target", "lib/main_staging.dart"]
56 | },
57 | {
58 | "name": "Production",
59 | "request": "launch",
60 | "type": "dart",
61 | "presentation": {
62 | "group": "launch"
63 | },
64 | "program": "lib/main.dart",
65 | "args": ["--flavor", "production", "--target", "lib/main.dart"]
66 | }
67 | ]
68 | }
69 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "flutter: flutter build apk",
8 | "type": "flutter",
9 | "command": "flutter",
10 | "args": [
11 | "build",
12 | "apk",
13 | "--flavor",
14 | "production",
15 | "--target",
16 | "lib/main.dart"
17 | ],
18 | "group": {
19 | "kind": "build",
20 | "isDefault": true
21 | },
22 | "problemMatcher": [],
23 | "presentation": {
24 | "reveal": "always",
25 | "focus": true,
26 | "showReuseMessage": false,
27 | "panel": "shared"
28 | }
29 | },
30 | {
31 | "label": "flutter: flutter build ios",
32 | "type": "flutter",
33 | "command": "flutter",
34 | "args": [
35 | "build",
36 | "ios",
37 | "--flavor",
38 | "production",
39 | "--target",
40 | "lib/main.dart"
41 | ],
42 | "group": "build",
43 | "problemMatcher": [],
44 | "presentation": {
45 | "reveal": "always",
46 | "focus": true,
47 | "showReuseMessage": false,
48 | "panel": "shared"
49 | }
50 | },
51 | {
52 | "label": "flutter: flutter test",
53 | "type": "flutter",
54 | "command": "flutter",
55 | "args": [
56 | "test",
57 | "--coverage",
58 | "--test-randomize-ordering-seed",
59 | "random"
60 | ],
61 | "group": "test",
62 | "problemMatcher": [],
63 | "presentation": {
64 | "reveal": "silent",
65 | "focus": true,
66 | "showReuseMessage": false,
67 | "panel": "shared"
68 | }
69 | },
70 | {
71 | "label": "flutter: flutter install",
72 | "type": "flutter",
73 | "command": "flutter",
74 | "args": [
75 | "install",
76 | "--flavor",
77 | "production",
78 | "--target",
79 | "lib/main.dart"
80 | ],
81 | "problemMatcher": [],
82 | }
83 | ]
84 | }
85 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Apparence
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ![coverage][coverage_badge]
7 | [![License: MIT][license_badge]][license_link]
8 |
9 |
10 |
11 | # **Slide puzzle flutter challenge 2022**
12 | 
13 | Developed with 💙 by Apparence.io
14 |
15 | Gameplay
16 | -
17 | This puzzle game is a bit different from other water pipes games. You can't rotate the pipes, only a slide is allowed! There's one empty space where you will be able to swipe your pipes and organize them to found a solution.
18 |
19 | **Move the pipes with your finger to create a way to let the water flow to the duck.
20 | Are you ready to play?
21 | [🦆 Click here to play !](https://flutter-challenge-2022.web.app/)**
22 |
23 | Features
24 | -
25 | - Random puzzle generation
26 | - Solvability checker, to make sure random generated puzzle have solution
27 | - Rive animations
28 | - Multiplatform (Web, iOS, Android)
29 | - Music & Sounds
30 | - Custom design
31 |
32 | Packages used
33 | -
34 | (confetti, dart_code_metrics, equatable, intl, just_audio, logging, rive, universal_platform)
35 |
36 |
37 |
38 | [coverage_badge]: coverage_badge.svg
39 | [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg
40 | [license_link]: https://opensource.org/licenses/MIT
41 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 | include: base_analysis_options.yaml
8 |
9 | linter:
10 | # The lint rules applied to this project can be customized in the
11 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
12 | # included above or to enable additional rules. A list of all available lints
13 | # and their documentation is published at
14 | # https://dart-lang.github.io/linter/lints/index.html.
15 | #
16 | # Instead of disabling a lint rule for the entire project in the
17 | # section below, it can also be suppressed for a single line of code
18 | # or a specific dart file by using the `// ignore: name_of_lint` and
19 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
20 | # producing the lint.
21 | rules:
22 | public_member_api_docs: false
23 |
24 | # Additional information about this file can be found at
25 | # https://dart.dev/guides/language/analysis-options
26 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | def keystoreProperties = new Properties()
25 | def keystorePropertiesFile = rootProject.file('key.properties')
26 | if (keystorePropertiesFile.exists()) {
27 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
28 | }
29 |
30 | apply plugin: 'com.android.application'
31 | apply plugin: 'kotlin-android'
32 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
33 |
34 | android {
35 | compileSdkVersion 31
36 |
37 | compileOptions {
38 | sourceCompatibility JavaVersion.VERSION_1_8
39 | targetCompatibility JavaVersion.VERSION_1_8
40 | }
41 |
42 | kotlinOptions {
43 | jvmTarget = '1.8'
44 | }
45 |
46 | sourceSets {
47 | main.java.srcDirs += 'src/main/kotlin'
48 | }
49 |
50 | defaultConfig {
51 | applicationId "io.apparence.flutter_puzzle_hack"
52 | minSdkVersion 16
53 | targetSdkVersion 31
54 | versionCode flutterVersionCode.toInteger()
55 | versionName flutterVersionName
56 | }
57 |
58 | signingConfigs {
59 | if (System.getenv("ANDROID_KEYSTORE_PATH")) {
60 | release {
61 | storeFile file(System.getenv("ANDROID_KEYSTORE_PATH"))
62 | keyAlias System.getenv("ANDROID_KEYSTORE_ALIAS")
63 | keyPassword System.getenv("ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD")
64 | storePassword System.getenv("ANDROID_KEYSTORE_PASSWORD")
65 | }
66 | } else {
67 | release {
68 | keyAlias keystoreProperties['keyAlias']
69 | keyPassword keystoreProperties['keyPassword']
70 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
71 | storePassword keystoreProperties['storePassword']
72 | }
73 | }
74 | }
75 |
76 | flavorDimensions "default"
77 | productFlavors {
78 | production {
79 | dimension "default"
80 | applicationIdSuffix ""
81 | manifestPlaceholders = [appName: "Flutter Puzzle Hack"]
82 | }
83 | staging {
84 | dimension "default"
85 | applicationIdSuffix ".stg"
86 | manifestPlaceholders = [appName: "[STG] Flutter Puzzle Hack"]
87 | }
88 | development {
89 | dimension "default"
90 | applicationIdSuffix ".dev"
91 | manifestPlaceholders = [appName: "[DEV] Flutter Puzzle Hack"]
92 | }
93 | }
94 |
95 | buildTypes {
96 | release {
97 | signingConfig signingConfigs.release
98 | minifyEnabled true
99 | useProguard true
100 | proguardFiles getDefaultProguardFile('proguard-android.txt')
101 | }
102 | debug {
103 | signingConfig signingConfigs.debug
104 | }
105 | }
106 | }
107 |
108 | flutter {
109 | source '../..'
110 | }
111 |
112 | dependencies {
113 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
114 | }
115 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
30 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/io/apparence/flutter_puzzle_hack/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package io.apparence.flutter_puzzle_hack
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/animations/apparence.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/animations/apparence.riv
--------------------------------------------------------------------------------
/assets/images/2.0x/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/2.0x/flutter_logo.png
--------------------------------------------------------------------------------
/assets/images/3.0x/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/3.0x/flutter_logo.png
--------------------------------------------------------------------------------
/assets/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/background.jpg
--------------------------------------------------------------------------------
/assets/images/buttons/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button.png
--------------------------------------------------------------------------------
/assets/images/buttons/button_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button_hover.png
--------------------------------------------------------------------------------
/assets/images/buttons/button_music_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button_music_off.png
--------------------------------------------------------------------------------
/assets/images/buttons/button_music_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button_music_on.png
--------------------------------------------------------------------------------
/assets/images/buttons/button_play_again_hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button_play_again_hover.png
--------------------------------------------------------------------------------
/assets/images/buttons/button_sound_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button_sound_off.png
--------------------------------------------------------------------------------
/assets/images/buttons/button_sound_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/buttons/button_sound_on.png
--------------------------------------------------------------------------------
/assets/images/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/flutter_logo.png
--------------------------------------------------------------------------------
/assets/images/glouglou.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/glouglou.png
--------------------------------------------------------------------------------
/assets/images/logos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/logos.png
--------------------------------------------------------------------------------
/assets/images/timer_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/images/timer_icon.png
--------------------------------------------------------------------------------
/assets/themes/base/audio/music.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/audio/music.mp3
--------------------------------------------------------------------------------
/assets/themes/base/audio/pop.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/audio/pop.wav
--------------------------------------------------------------------------------
/assets/themes/base/tile_cross.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_cross.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_end.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_end.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_horizontal.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_horizontal.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_left_bottom.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_left_bottom.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_left_top.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_left_top.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_right_bottom.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_right_bottom.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_start.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_start.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_top_right.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_top_right.riv
--------------------------------------------------------------------------------
/assets/themes/base/tile_vertical.riv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/assets/themes/base/tile_vertical.riv
--------------------------------------------------------------------------------
/coverage_badge.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": {
3 | "public": "build/web",
4 | "site": "apparence-flutter-puzzle",
5 | "cleanUrls": true,
6 | "trailingSlash": false,
7 | "ignore": [".firebase", "firebase.json", "__/**"]
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 9.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | end
36 |
37 | post_install do |installer|
38 | installer.pods_project.targets.each do |target|
39 | flutter_additional_ios_build_settings(target)
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/development.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/production.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/staging.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
45 |
51 |
52 |
53 |
54 |
60 |
62 |
68 |
69 |
70 |
71 |
73 |
74 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Apparence-io/flutter-challenge/b63446634a3fdc5e4edc8879a71339766e6bc1cb/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | $(FLAVOR_APP_NAME)
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | flutter_puzzle_hack
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/l10n.yaml:
--------------------------------------------------------------------------------
1 | arb-dir: lib/src/l10n/arb
2 | template-arb-file: app_en.arb
3 | output-localization-file: app_localizations.dart
4 | nullable-getter: false
5 |
--------------------------------------------------------------------------------
/lib/boostrap.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:logging/logging.dart';
5 |
6 | Future bootstrap(
7 | FutureOr Function() builder,
8 | FlavorConfig flavorConfig,
9 | ) async {
10 | AppLogger.init(flavorConfig);
11 | FlutterError.onError = Logger('error').severe;
12 |
13 | Logger('bootstrap')
14 | ..info('------------------------------')
15 | ..info('Starting Flutter Puzzle Hack')
16 | ..info('$flavorConfig')
17 | ..info('------------------------------');
18 |
19 | runApp(await builder());
20 | }
21 |
22 | // ignore: prefer-match-file-name
23 | enum Flavor { development, staging, test, production }
24 |
25 | class FlavorConfig {
26 | FlavorConfig(this.flavor, this.logLevel);
27 |
28 | factory FlavorConfig.development() =>
29 | FlavorConfig(Flavor.development, Level.ALL);
30 |
31 | factory FlavorConfig.test() => FlavorConfig(Flavor.test, Level.ALL);
32 |
33 | factory FlavorConfig.staging() => FlavorConfig(Flavor.staging, Level.INFO);
34 |
35 | factory FlavorConfig.production() =>
36 | FlavorConfig(Flavor.production, Level.SEVERE);
37 |
38 | final Flavor flavor;
39 | final Level logLevel;
40 |
41 | @override
42 | String toString() {
43 | return 'FlavorConfig { flavor: ${flavor.name}, logLevel: $logLevel }';
44 | }
45 | }
46 |
47 | class AppLogger {
48 | AppLogger(this.flavorConfig);
49 |
50 | static late final AppLogger instance;
51 |
52 | final FlavorConfig flavorConfig;
53 |
54 | static void init(FlavorConfig flavorConfig) {
55 | AppLogger.instance = AppLogger(flavorConfig);
56 | AppLogger.instance._init();
57 | }
58 |
59 | void _init() {
60 | Logger.root.level = flavorConfig.logLevel;
61 | if (flavorConfig.flavor != Flavor.production) {
62 | Logger.root.onRecord.listen(_logToStdout);
63 | }
64 | }
65 |
66 | void _logToStdout(LogRecord record) {
67 | debugPrint('${record.level.name}: ${record.time}: ${record.message}');
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_puzzle_hack/boostrap.dart';
2 | import 'package:flutter_puzzle_hack/src/app.dart';
3 |
4 | Future main() async {
5 | await bootstrap(
6 | App.new,
7 | FlavorConfig.production(),
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/lib/main_development.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_puzzle_hack/boostrap.dart';
2 | import 'package:flutter_puzzle_hack/src/app.dart';
3 |
4 | Future main() async {
5 | await bootstrap(
6 | App.new,
7 | FlavorConfig.development(),
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/lib/main_staging.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_puzzle_hack/boostrap.dart';
2 | import 'package:flutter_puzzle_hack/src/app.dart';
3 |
4 | Future main() async {
5 | await bootstrap(
6 | App.new,
7 | FlavorConfig.staging(),
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/lib/src/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
3 | import 'package:flutter_localizations/flutter_localizations.dart';
4 | import 'package:flutter_puzzle_hack/src/layout/breakpoint_provider.dart';
5 | import 'package:flutter_puzzle_hack/src/puzzle/view/puzzle_page.dart';
6 |
7 | import 'package:flutter_puzzle_hack/src/splashscreen/splashscreen.dart';
8 | import 'package:flutter_puzzle_hack/src/theme/app_theme.dart';
9 |
10 | /// The Widget that configures your application.
11 | class App extends StatelessWidget {
12 | const App({
13 | Key? key,
14 | this.initialRoute = 'splashscreen',
15 | }) : super(key: key);
16 |
17 | final String? initialRoute;
18 |
19 | Route? generateRoute(RouteSettings routeSettings) {
20 | return MaterialPageRoute(
21 | settings: routeSettings,
22 | builder: (BuildContext context) {
23 | switch (routeSettings.name) {
24 | case 'splashscreen':
25 | return Splashscreen(
26 | onDone: () => Navigator.pushReplacementNamed(context, '/'),
27 | );
28 | case '/':
29 | default:
30 | return const PuzzlePage();
31 | }
32 | },
33 | );
34 | }
35 |
36 | @override
37 | Widget build(BuildContext context) {
38 | return MaterialApp(
39 | // Providing a restorationScopeId allows the Navigator built by the
40 | // MaterialApp to restore the navigation stack when a user leaves and
41 | // returns to the app after it has been killed while running in the
42 | // background.
43 | restorationScopeId: 'app',
44 |
45 | // Provide the generated AppLocalizations to the MaterialApp. This
46 | // allows descendant Widgets to display the correct translations
47 | // depending on the user's locale.
48 | localizationsDelegates: const [
49 | AppLocalizations.delegate,
50 | GlobalMaterialLocalizations.delegate,
51 | GlobalWidgetsLocalizations.delegate,
52 | GlobalCupertinoLocalizations.delegate,
53 | ],
54 | supportedLocales: AppLocalizations.supportedLocales,
55 |
56 | // Use AppLocalizations to configure the correct application title
57 | // depending on the user's locale.
58 | //
59 | // The appTitle is defined in .arb files found in the localization
60 | // directory.
61 | onGenerateTitle: (BuildContext context) =>
62 | AppLocalizations.of(context).appTitle,
63 | theme: AppTheme.dark,
64 | darkTheme: AppTheme.dark,
65 | themeMode: ThemeMode.dark,
66 |
67 | // Define a function to handle named routes in order to support
68 | // Flutter web url navigation and deep linking.
69 | initialRoute: initialRoute,
70 | onGenerateRoute: generateRoute,
71 | builder: (context, child) => BreakpointProvider(
72 | screenWidth: MediaQuery.of(context).size.width,
73 | child: child ?? const SizedBox.shrink(),
74 | ),
75 | );
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/lib/src/l10n/arb/app_en.arb:
--------------------------------------------------------------------------------
1 | {
2 | "@@locale": "en",
3 | "appTitle": "Flutter Puzzle Hack 2022",
4 | "@appTitle": {
5 | "description": "The title of the application"
6 | },
7 | "puzzlePageTitle": "Flutter Puzzle Hack 2022",
8 | "@puzzlePageTitle": {
9 | "description": "The title of Puzzle Page"
10 | },
11 | "puzzlePageSubTitle": "To win, splash the duck.",
12 | "@appTitle": {
13 | "description": "The subtitle of the application"
14 | },
15 | "buttonStartText": "Start Game",
16 | "@buttonStartText": {
17 | "description": "Start the game"
18 | },
19 | "buttonRestartText": "Restart Game",
20 | "@buttonRestartText": {
21 | "description": "Restart the game"
22 | },
23 | "puzzleDurationLabelText": "{hours} hours {minutes} minutes {seconds} seconds",
24 | "@puzzleDurationLabelText": {
25 | "description": "Semantic for the puzzle timer",
26 | "placeholders": {
27 | "hours": {
28 | "type": "String",
29 | "example": "1"
30 | },
31 | "minutes": {
32 | "type": "String",
33 | "example": "21"
34 | },
35 | "seconds": {
36 | "type": "String",
37 | "example": "42"
38 | }
39 | }
40 | },
41 | "nMoves": "{count,plural, =0{{count} move} =1{{count} move} other{{count} moves}}",
42 | "@nMoves": {
43 | "description": "Shown as a number of moves",
44 | "placeholders": {
45 | "count": {
46 | "type": "int"
47 | }
48 | }
49 | },
50 | "puzzleVictoryDialogTitle": "You've Won!",
51 | "@puzzleVictoryDialogTitle": {
52 | "description": "Title of the victory dialog"
53 | },
54 | "puzzleVictoryDialogDescription": "Your score:",
55 | "@puzzleVictoryDialogDescription": {
56 | "description": "Description of the victory dialog"
57 | },
58 | "buttonCloseLabel": "Close",
59 | "@buttonCloseLabel": {
60 | "description": "Close button label of the victory dialog"
61 | }
62 | }
--------------------------------------------------------------------------------
/lib/src/l10n/arb/app_fr.arb:
--------------------------------------------------------------------------------
1 | {
2 | "@@locale": "fr",
3 | "appTitle": "Flutter Puzzle Hack 2022",
4 | "@appTitle": {
5 | "description": "Le titre de l'application"
6 | },
7 | "puzzlePageTitle": "Flutter Puzzle Hack 2022",
8 | "@puzzlePageTitle": {
9 | "description": "Le titre de la page du puzzle"
10 | },
11 | "puzzlePageSubTitle": "Pour gagner, arrose le canard",
12 | "@appTitle": {
13 | "description": "Le sous-titre de la page du puzzle"
14 | },
15 | "buttonStartText": "Commencer",
16 | "@buttonStartText": {
17 | "description": "Démarrage du jeu"
18 | },
19 | "buttonRestartText": "Recommencer",
20 | "@buttonRestartText": {
21 | "description": "Redémarrage du jeu"
22 | },
23 | "puzzleDurationLabelText": "{hours} heures {minutes} minutes {seconds} secondes",
24 | "@puzzleDurationLabelText": {
25 | "description": "Sémantique pour le chronomètre du puzzle",
26 | "placeholders": {
27 | "hours": {
28 | "type": "String",
29 | "example": "1"
30 | },
31 | "minutes": {
32 | "type": "String",
33 | "example": "21"
34 | },
35 | "seconds": {
36 | "type": "String",
37 | "example": "42"
38 | }
39 | }
40 | },
41 | "nMoves": "{count,plural, =0{{count} mouvement} =1{{count} mouvement} other{{count} mouvements}}",
42 | "@nMoves": {
43 | "description": "Affiché en tant que nombre de mouvements",
44 | "placeholders": {
45 | "count": {
46 | "type": "int"
47 | }
48 | }
49 | },
50 | "puzzleVictoryDialogTitle": "Tu as gagné !",
51 | "@puzzleVictoryDialogTitle": {
52 | "description": "Titre du dialogue de victoire"
53 | },
54 | "puzzleVictoryDialogDescription": "Ton score :",
55 | "@puzzleVictoryDialogDescription": {
56 | "description": "Description du dialogue de victoire"
57 | },
58 | "buttonCloseLabel": "Fermer",
59 | "@buttonCloseLabel": {
60 | "description": "Label du bouton fermer du dialogue de victoire"
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/lib/src/l10n/l10n.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
3 |
4 | export 'package:flutter_gen/gen_l10n/app_localizations.dart';
5 |
6 | // ignore: prefer-match-file-name
7 | extension AppLocalizationsX on BuildContext {
8 | AppLocalizations get l10n => AppLocalizations.of(this);
9 | }
10 |
--------------------------------------------------------------------------------
/lib/src/layout/breakpoint_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | Breakpoint _getBreakpoint(double screenWidth) {
4 | var breakpoint = Breakpoint.xsmall;
5 | if (screenWidth >= BreakpointSize.xlarge) {
6 | breakpoint = Breakpoint.xlarge;
7 | } else if (screenWidth >= BreakpointSize.large) {
8 | breakpoint = Breakpoint.large;
9 | } else if (screenWidth >= BreakpointSize.medium) {
10 | breakpoint = Breakpoint.medium;
11 | } else if (screenWidth >= BreakpointSize.small) {
12 | breakpoint = Breakpoint.small;
13 | }
14 |
15 | return breakpoint;
16 | }
17 |
18 | /// {@template BreakpointProvider}
19 | /// A provider for various responsive breakpoints.
20 | /// {@endtemplate}
21 | class BreakpointProvider extends InheritedWidget {
22 | BreakpointProvider({
23 | Key? key,
24 | required this.screenWidth,
25 | required Widget child,
26 | }) : breakpoint = _getBreakpoint(screenWidth),
27 | super(key: key, child: child);
28 |
29 | final double screenWidth;
30 | final Breakpoint breakpoint;
31 |
32 | static Breakpoint of(BuildContext context) {
33 | return context
34 | .dependOnInheritedWidgetOfExactType()!
35 | .breakpoint;
36 | }
37 |
38 | @override
39 | bool updateShouldNotify(BreakpointProvider oldWidget) =>
40 | oldWidget.breakpoint != breakpoint;
41 | }
42 |
43 | abstract class BreakpointSize {
44 | static const double small = 600;
45 | static const double medium = 900;
46 | static const double large = 1200;
47 | static const double xlarge = 1536;
48 | }
49 |
50 | enum Breakpoint {
51 | xsmall,
52 | small,
53 | medium,
54 | large,
55 | xlarge,
56 | }
57 |
--------------------------------------------------------------------------------
/lib/src/layout/responsive_layout_builder.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_puzzle_hack/src/layout/breakpoint_provider.dart';
3 |
4 | typedef ResponsiveLayoutWidgetBuilder = Widget Function(BuildContext, Widget?);
5 |
6 | Map _createBuilders({
7 | ResponsiveLayoutWidgetBuilder? xsmall,
8 | ResponsiveLayoutWidgetBuilder? small,
9 | ResponsiveLayoutWidgetBuilder? medium,
10 | ResponsiveLayoutWidgetBuilder? large,
11 | ResponsiveLayoutWidgetBuilder? xlarge,
12 | }) {
13 | final map = {};
14 | ResponsiveLayoutWidgetBuilder? last;
15 | map[Breakpoint.xsmall] = last = xsmall ?? last;
16 | map[Breakpoint.small] = last = small ?? last;
17 | map[Breakpoint.medium] = last = medium ?? last;
18 | map[Breakpoint.large] = last = large ?? last;
19 | map[Breakpoint.xlarge] = last = xlarge ?? last;
20 |
21 | return map;
22 | }
23 |
24 | /// {@template ResponsiveLayoutBuilder}
25 | /// A wrapper around [LayoutBuilder] which exposes optionnal builders for
26 | /// various responsive breakpoints.
27 | ///
28 | /// If no builder is provided for given breakpoint, a smaller breakpoint builder
29 | /// will be used.
30 | ///
31 | /// If no breakpoint builder is found, the child widget builder will be used.
32 | /// {@endtemplate}
33 | class ResponsiveLayoutBuilder extends StatelessWidget {
34 | ResponsiveLayoutBuilder({
35 | Key? key,
36 | ResponsiveLayoutWidgetBuilder? xsmall,
37 | ResponsiveLayoutWidgetBuilder? small,
38 | ResponsiveLayoutWidgetBuilder? medium,
39 | ResponsiveLayoutWidgetBuilder? large,
40 | ResponsiveLayoutWidgetBuilder? xlarge,
41 | this.child,
42 | }) : builders = _createBuilders(
43 | xsmall: xsmall,
44 | small: small,
45 | medium: medium,
46 | large: large,
47 | xlarge: xlarge,
48 | ),
49 | super(key: key);
50 |
51 | final Map builders;
52 |
53 | /// Optional child widget builder based on the current layout size
54 | /// which will be passed to the `xsmall`, `small`, `medium`, `large` and
55 | /// `xlarge` builders as a way to share/optimize shared layout.
56 | final Widget Function(Breakpoint breakpoint)? child;
57 |
58 | @override
59 | Widget build(BuildContext context) {
60 | return LayoutBuilder(
61 | builder: (context, constraints) {
62 | final breakpoint = BreakpointProvider.of(context);
63 |
64 | final builder = builders[breakpoint];
65 |
66 | return builder?.call(context, child?.call(breakpoint)) ??
67 | child!.call(breakpoint);
68 | },
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/lib/src/models/connection.dart:
--------------------------------------------------------------------------------
1 | import 'package:equatable/equatable.dart';
2 |
3 | /// {@template connection}
4 | /// Tile connection model defining how tiles interact.
5 | ///
6 | /// A left tile having a right connection can connect
7 | /// with a right tile having a left connection.
8 | /// {@endtemplate}
9 | class Connection extends Equatable {
10 | // ignore: avoid_positional_boolean_parameters
11 | const Connection.fromLTRB(this.left, this.top, this.right, this.bottom);
12 |
13 | // ignore: avoid_positional_boolean_parameters
14 | const Connection.all(bool value)
15 | : left = value,
16 | top = value,
17 | right = value,
18 | bottom = value;
19 |
20 | const Connection.horizontal()
21 | : left = true,
22 | top = false,
23 | right = true,
24 | bottom = false;
25 |
26 | const Connection.vertical()
27 | : left = false,
28 | top = true,
29 | right = false,
30 | bottom = true;
31 |
32 | const Connection.leftTop()
33 | : left = true,
34 | top = true,
35 | right = false,
36 | bottom = false;
37 |
38 | const Connection.topRight()
39 | : left = false,
40 | top = true,
41 | right = true,
42 | bottom = false;
43 |
44 | const Connection.leftBottom()
45 | : left = true,
46 | top = false,
47 | right = false,
48 | bottom = true;
49 |
50 | const Connection.rightBottom()
51 | : left = false,
52 | top = false,
53 | right = true,
54 | bottom = true;
55 |
56 | final bool left;
57 | final bool top;
58 | final bool right;
59 | final bool bottom;
60 |
61 | @override
62 | List