├── assets └── logo.png ├── screenshots ├── home_screen.jpg └── history_screen.jpg ├── lib ├── core │ └── constants.dart ├── features │ ├── history_screen │ │ ├── logic │ │ │ └── hive_history.dart │ │ └── presentation │ │ │ ├── widgets │ │ │ ├── delete_history_dialog.dart │ │ │ └── history_score_card.dart │ │ │ └── history_screen.dart │ └── home_screen │ │ ├── logic │ │ ├── reset_history.dart │ │ ├── hive_functions.dart │ │ └── check_target.dart │ │ └── presentation │ │ ├── widgets │ │ ├── custom_score_goal_widget.dart │ │ ├── custom_app_bar.dart │ │ ├── app_footer.dart │ │ ├── score_history_section.dart │ │ ├── custom_buttons.dart │ │ ├── edit_name_dialog.dart │ │ ├── add_points_dialog.dart │ │ └── custom_team_score.dart │ │ └── home_screen.dart ├── shared │ └── models │ │ ├── game_model.dart │ │ ├── game_model.g.dart │ │ ├── team_model.g.dart │ │ └── team_model.dart └── main.dart ├── android ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── 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 │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night │ │ │ │ │ └── styles.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── dominos_notebook │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle └── settings.gradle ├── .gitignore ├── README.md ├── analysis_options.yaml ├── .metadata ├── pubspec.yaml └── pubspec.lock /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/assets/logo.png -------------------------------------------------------------------------------- /screenshots/home_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/screenshots/home_screen.jpg -------------------------------------------------------------------------------- /screenshots/history_screen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/screenshots/history_screen.jpg -------------------------------------------------------------------------------- /lib/core/constants.dart: -------------------------------------------------------------------------------- 1 | import '../shared/models/game_model.dart'; 2 | import '../shared/models/team_model.dart'; 3 | 4 | List historyGames = []; 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BenferhatAymen/dominos-notebook-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/dominos_notebook/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.dominos_notebook 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | org.gradle.java.home=C:/Program Files/Java/jdk-17 5 | -------------------------------------------------------------------------------- /lib/features/history_screen/logic/hive_history.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive_flutter/hive_flutter.dart'; 2 | 3 | import '../../../shared/models/game_model.dart'; 4 | 5 | List readHistory(Box box) { 6 | return box.get("History") ?? []; 7 | } 8 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip 6 | -------------------------------------------------------------------------------- /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/to/reference-keystore 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /lib/features/home_screen/logic/reset_history.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/core/constants.dart'; 2 | import 'package:dominos_notebook/features/home_screen/logic/hive_functions.dart'; 3 | import 'package:hive_flutter/hive_flutter.dart'; 4 | 5 | void resetHistory() { 6 | historyGames.clear(); 7 | resetHiveHistory(); 8 | } 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/shared/models/game_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/shared/models/team_model.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:hive/hive.dart'; 4 | 5 | part 'game_model.g.dart'; 6 | 7 | 8 | @HiveType(typeId: 1) 9 | class Game extends HiveObject { 10 | @HiveField(0) 11 | final Team teamA; 12 | @HiveField(1) 13 | final Team teamB; 14 | 15 | Game({required this.teamA, required this.teamB}); 16 | } 17 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /lib/features/home_screen/logic/hive_functions.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive/hive.dart'; 2 | 3 | import 'package:hive_flutter/hive_flutter.dart'; 4 | 5 | import '../../../shared/models/team_model.dart'; 6 | 7 | void writeTeamA(Box box, Team teamA) { 8 | box.put('TeamA', teamA); 9 | print(box.get("TeamA")); 10 | } 11 | 12 | void writeTeamB(Box box, Team teamB) { 13 | box.put('TeamB', teamB); 14 | print(box.get("TeamB")); 15 | } 16 | 17 | void resetHiveHistory() { 18 | var box = Hive.box("dominos"); 19 | box.delete("History"); 20 | } 21 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "8.1.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .build/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | .swiftpm/ 13 | migrate_working_dir/ 14 | 15 | # IntelliJ related 16 | *.iml 17 | *.ipr 18 | *.iws 19 | .idea/ 20 | 21 | # The .vscode folder contains launch configuration and tasks you configure in 22 | # VS Code which you may wish to be included in version control, so this line 23 | # is commented out by default. 24 | #.vscode/ 25 | 26 | # Flutter/Dart/Pub related 27 | **/doc/api/ 28 | **/ios/Flutter/.last_build_id 29 | .dart_tool/ 30 | .flutter-plugins 31 | .flutter-plugins-dependencies 32 | .pub-cache/ 33 | .pub/ 34 | /build/ 35 | 36 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Android Studio will place build artifacts here 43 | /android/app/debug 44 | /android/app/profile 45 | /android/app/release 46 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/shared/models/game_model.dart'; 2 | import 'package:dominos_notebook/shared/models/team_model.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:hive/hive.dart'; 5 | import 'package:hive_flutter/hive_flutter.dart'; 6 | 7 | import 'features/home_screen/presentation/home_screen.dart'; 8 | 9 | void main() async { 10 | await Hive.initFlutter(); 11 | Hive.registerAdapter(TeamAdapter()); 12 | Hive.registerAdapter(GameAdapter()); 13 | await Hive.openBox("dominos"); 14 | // var mainbox = Hive.box("dominos"); 15 | // mainbox.clear(); 16 | runApp(DominosNoteBookApp()); 17 | } 18 | 19 | class DominosNoteBookApp extends StatelessWidget { 20 | const DominosNoteBookApp({super.key}); 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return MaterialApp( 25 | debugShowCheckedModeBanner: false, 26 | home: HomeScreen(), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/custom_score_goal_widget.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/material.dart'; 3 | import 'package:google_fonts/google_fonts.dart'; 4 | 5 | 6 | class CustomScoreGoalWidget extends StatelessWidget { 7 | const CustomScoreGoalWidget({super.key, required this.goalScore}); 8 | final int goalScore; 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Container( 13 | decoration: BoxDecoration( 14 | color: Color(0xffD9D9D9).withOpacity(0.1), 15 | borderRadius: BorderRadius.circular( 16 | 16, 17 | ), 18 | ), 19 | padding: EdgeInsets.only( 20 | left: 8, 21 | right: 15, 22 | top: 4, 23 | bottom: 4, 24 | ), 25 | child: Column( 26 | mainAxisAlignment: MainAxisAlignment.center, 27 | crossAxisAlignment: CrossAxisAlignment.start, 28 | children: [ 29 | Text( 30 | goalScore.toString(), 31 | style: GoogleFonts.inter( 32 | color: Colors.white, 33 | fontSize: 16, 34 | fontWeight: FontWeight.w600, 35 | ), 36 | ), 37 | ]), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/shared/models/game_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'game_model.dart'; 4 | 5 | // ************************************************************************** 6 | // TypeAdapterGenerator 7 | // ************************************************************************** 8 | 9 | class GameAdapter extends TypeAdapter { 10 | @override 11 | final int typeId = 1; 12 | 13 | @override 14 | Game read(BinaryReader reader) { 15 | final numOfFields = reader.readByte(); 16 | final fields = { 17 | for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), 18 | }; 19 | return Game( 20 | teamA: fields[0] as Team, 21 | teamB: fields[1] as Team, 22 | ); 23 | } 24 | 25 | @override 26 | void write(BinaryWriter writer, Game obj) { 27 | writer 28 | ..writeByte(2) 29 | ..writeByte(0) 30 | ..write(obj.teamA) 31 | ..writeByte(1) 32 | ..write(obj.teamB); 33 | } 34 | 35 | @override 36 | int get hashCode => typeId.hashCode; 37 | 38 | @override 39 | bool operator ==(Object other) => 40 | identical(this, other) || 41 | other is GameAdapter && 42 | runtimeType == other.runtimeType && 43 | typeId == other.typeId; 44 | } 45 | -------------------------------------------------------------------------------- /lib/shared/models/team_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'team_model.dart'; 4 | 5 | // ************************************************************************** 6 | // TypeAdapterGenerator 7 | // ************************************************************************** 8 | 9 | class TeamAdapter extends TypeAdapter { 10 | @override 11 | final int typeId = 0; 12 | 13 | @override 14 | Team read(BinaryReader reader) { 15 | final numOfFields = reader.readByte(); 16 | final fields = { 17 | for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), 18 | }; 19 | return Team( 20 | name: fields[0] as String, 21 | ) 22 | .._points = fields[1] as int 23 | .._gamePoints = (fields[2] as List).cast(); 24 | } 25 | 26 | @override 27 | void write(BinaryWriter writer, Team obj) { 28 | writer 29 | ..writeByte(3) 30 | ..writeByte(0) 31 | ..write(obj.name) 32 | ..writeByte(1) 33 | ..write(obj._points) 34 | ..writeByte(2) 35 | ..write(obj._gamePoints); 36 | } 37 | 38 | @override 39 | int get hashCode => typeId.hashCode; 40 | 41 | @override 42 | bool operator ==(Object other) => 43 | identical(this, other) || 44 | other is TeamAdapter && 45 | runtimeType == other.runtimeType && 46 | typeId == other.typeId; 47 | } 48 | -------------------------------------------------------------------------------- /lib/shared/models/team_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:hive/hive.dart'; 2 | part 'team_model.g.dart'; 3 | 4 | @HiveType(typeId: 0) 5 | class Team { 6 | @HiveField(0) 7 | String name; 8 | @HiveField(1) 9 | int _points = 0; 10 | @HiveField(2) 11 | List _gamePoints = []; 12 | 13 | Team({required this.name}); 14 | @override 15 | String toString() { 16 | return 'Team(name: $name, score: $_points)'; 17 | } 18 | 19 | void addPoints(int points) { 20 | _points += points; 21 | } 22 | 23 | int getPoints() { 24 | return _points; 25 | } 26 | 27 | List getGamePoints() { 28 | return List.from(_gamePoints); 29 | } 30 | 31 | void resetPoints() { 32 | _points = 0; 33 | } 34 | 35 | void clearPoints() { 36 | this._gamePoints = []; 37 | } 38 | 39 | setGamepints(List teamPoints) { 40 | this._gamePoints.addAll(teamPoints); 41 | } 42 | 43 | void undoPoint() { 44 | int substraction; 45 | if (this._gamePoints.last == "-") { 46 | substraction = 0; 47 | } else { 48 | substraction = int.parse(this._gamePoints.last); 49 | } 50 | this._points = this._points - substraction; 51 | this._gamePoints.removeLast(); 52 | } 53 | 54 | void addGamePoints(String points) { 55 | addPoints(int.parse(points)); 56 | if (points == "0") { 57 | _gamePoints.add("-"); 58 | } else { 59 | _gamePoints.add(points); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dominos Notebook 2 | 3 | A simple Flutter app to keep track of team scores while playing Dominos. 4 | 5 | ## Features 6 | 7 | - Edit team names 8 | - Add points 9 | - Reset scores 10 | - Data saved locally using Hive 11 | 12 | ## Tech Stack 13 | 14 | - Flutter 15 | - Hive for local storage 16 | 17 | ## Getting Started 18 | 19 | ```bash 20 | git clone https://github.com/yourusername/dominos-notebook-app.git 21 | cd dominos-notebook-app 22 | flutter pub get 23 | flutter run 24 | ``` 25 | 26 | ## Project Structure 27 | ``` 28 | lib/ 29 | ├── core/ 30 | ├── features/ 31 | │ ├── home_screen/ 32 | │ │ ├── logic/ 33 | │ │ └── presentation/ 34 | │ └── history_screen/ 35 | │ ├── logic/ 36 | │ └── presentation/ 37 | ├── shared/ 38 | │ └── models/ 39 | │── main.dart 40 | ``` 41 | 42 | 43 | ## Screenshots 44 | 45 | ### Home Screen 46 | ![Home Screen](screenshots/home_screen.jpg) 47 | 48 | ### History Screen 49 | ![History Screen](screenshots/history_screen.jpg) 50 | 51 | 52 | ## Download 53 | You can download the app from the following link: 54 | 55 | [Download Domino's Notebook](https://www.mediafire.com/file/ztct5fq8da75hnc/app-arm64-v8a-release%25282%2529.apk/file) 56 | 57 | ## Licence 58 | 59 | Copyright (c) 2025 Benferhat Aymen 60 | 61 | Permission is granted to use, copy, modify, and distribute this software for any purpose with or without fee. 62 | 63 | The software is provided "as is", without warranty of any kind. 64 | -------------------------------------------------------------------------------- /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 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | android { 9 | namespace = "com.example.dominos_notebook" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_1_8 15 | targetCompatibility = JavaVersion.VERSION_1_8 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_1_8 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.example.dominos_notebook" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = flutter.minSdkVersion 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.debug 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/custom_app_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_fonts/google_fonts.dart'; 3 | 4 | class CustomAppBar extends StatelessWidget { 5 | const CustomAppBar({ 6 | super.key, 7 | required this.size, 8 | required this.title, 9 | }); 10 | 11 | final Size size; 12 | final String title; 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | height: size.height * 0.07, 17 | child: Row( 18 | mainAxisAlignment: MainAxisAlignment.center, 19 | children: [ 20 | SizedBox( 21 | width: size.width * 0.28, 22 | ), 23 | Center( 24 | child: Text( 25 | title, 26 | style: GoogleFonts.bonaNova( 27 | color: Colors.white, 28 | fontWeight: FontWeight.w700, 29 | fontSize: 32, 30 | ), 31 | ), 32 | ), 33 | Spacer(), 34 | Center( 35 | child: Container( 36 | child: Column( 37 | children: [ 38 | Icon( 39 | Icons.settings, 40 | color: Colors.white, 41 | size: 26, 42 | ), 43 | Spacer(), 44 | Icon( 45 | Icons.share, 46 | color: Colors.white, 47 | size: 26, 48 | ), 49 | ], 50 | ), 51 | ), 52 | ), 53 | ], 54 | ), 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/features/home_screen/logic/check_target.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/core/constants.dart'; 2 | import 'package:dominos_notebook/features/home_screen/logic/hive_functions.dart'; 3 | import 'package:dominos_notebook/shared/models/game_model.dart'; 4 | import 'package:hive_flutter/hive_flutter.dart'; 5 | 6 | import '../../../shared/models/team_model.dart'; 7 | 8 | void ResetGame(Team teamA, Team teamB) { 9 | Team copyTeamA = Team(name: teamA.name); 10 | copyTeamA.addPoints(teamA.getPoints()); 11 | copyTeamA.setGamepints(teamA.getGamePoints()); 12 | Team copyTeamB = Team(name: teamB.name); 13 | copyTeamB.addPoints(teamB.getPoints()); 14 | copyTeamB.setGamepints(teamB.getGamePoints()); 15 | Game gameScore = Game(teamA: copyTeamA, teamB: copyTeamB); 16 | historyGames.add(gameScore); 17 | updateHistory(gameScore); 18 | restartGame(teamA, teamB); 19 | resetTeamsInLocalStorage(teamA, teamB); 20 | } 21 | 22 | bool checkTarget(Team teamA, Team teamB, int targetScore) { 23 | return teamA.getPoints() >= targetScore || teamB.getPoints() >= targetScore; 24 | } 25 | 26 | void restartGame(Team teamA, Team teamB) { 27 | teamA.resetPoints(); 28 | teamB.resetPoints(); 29 | teamA.clearPoints(); 30 | teamB.clearPoints(); 31 | } 32 | 33 | void resetTeamsInLocalStorage(Team teamA, Team teamB) { 34 | Box box = Hive.box("dominos"); 35 | Team copyTeamA = Team(name: teamA.name); 36 | Team copyTeamB = Team(name: teamB.name); 37 | writeTeamA(box, copyTeamA); 38 | writeTeamB(box, copyTeamB); 39 | } 40 | 41 | void updateHistory(Game game) { 42 | Box box = Hive.box("dominos"); 43 | List history = box.get("History") ?? []; 44 | 45 | history.add(game); 46 | box.put('History', history); 47 | } 48 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/app_footer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:hive_flutter/hive_flutter.dart'; 3 | 4 | import '../../../../shared/models/team_model.dart'; 5 | import '../../../history_screen/presentation/history_screen.dart'; 6 | import 'custom_buttons.dart'; 7 | 8 | class AppFooter extends StatelessWidget { 9 | AppFooter({super.key, required this.size, this.onSave}); 10 | 11 | final Size size; 12 | void Function()? onSave; 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Padding( 17 | padding: EdgeInsets.symmetric(horizontal: size.width * 0.05), 18 | child: Row( 19 | children: [ 20 | IconButton( 21 | onPressed: () { 22 | Navigator.push( 23 | context, 24 | MaterialPageRoute( 25 | builder: (context) => MatchHistoryScreen())); 26 | }, 27 | icon: Icon( 28 | Icons.history, 29 | color: Colors.blue, 30 | size: 44, 31 | ), 32 | ), 33 | SizedBox( 34 | width: size.width * 0.05, 35 | ), 36 | Expanded( 37 | child: CustomRestartButton( 38 | size: size, 39 | onSave: onSave, 40 | )), 41 | SizedBox( 42 | width: size.width * 0.05, 43 | ), 44 | IconButton( 45 | icon: Icon( 46 | Icons.star_border, 47 | color: Colors.yellow, 48 | size: 44, 49 | ), 50 | onPressed: () { 51 | var box = Hive.box("dominos"); 52 | print(box.get("TeamA")); 53 | }, 54 | ), 55 | ], 56 | ), 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.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: "d8a9f9a52e5af486f80d932e838ee93861ffd863" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 17 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 18 | - platform: android 19 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 20 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 21 | - platform: ios 22 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 23 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 24 | - platform: linux 25 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 26 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 27 | - platform: macos 28 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 29 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 30 | - platform: web 31 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 32 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 33 | - platform: windows 34 | create_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 35 | base_revision: d8a9f9a52e5af486f80d932e838ee93861ffd863 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/features/history_screen/presentation/widgets/delete_history_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DeleteHistoryDialog extends StatelessWidget { 4 | DeleteHistoryDialog({ 5 | super.key, 6 | this.onSave, 7 | this.title = "Are you sure?", 8 | this.onChanged, 9 | }); 10 | VoidCallback? onSave; 11 | Function(String)? onChanged; 12 | String title; 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | var media = MediaQuery.sizeOf(context); 17 | return AlertDialog( 18 | backgroundColor: const Color.fromARGB(255, 0, 8, 15), 19 | title: Center( 20 | child: Text( 21 | title, 22 | style: TextStyle( 23 | color: Colors.white, 24 | fontWeight: FontWeight.w600, 25 | fontSize: 20, 26 | ), 27 | ), 28 | ), 29 | content: Column( 30 | mainAxisSize: MainAxisSize.min, 31 | crossAxisAlignment: CrossAxisAlignment.start, 32 | children: [ 33 | Row( 34 | mainAxisSize: MainAxisSize.min, 35 | children: [ 36 | Expanded( 37 | child: ElevatedButton( 38 | onPressed: () { 39 | onSave!(); 40 | Navigator.pop(context); 41 | }, 42 | child: const Text( 43 | "Delete", 44 | style: TextStyle( 45 | color: Colors.red, 46 | fontSize: 16, 47 | fontWeight: FontWeight.w700, 48 | ), 49 | ), 50 | style: ElevatedButton.styleFrom( 51 | backgroundColor: Colors.black, 52 | shape: RoundedRectangleBorder( 53 | borderRadius: BorderRadius.circular(12), 54 | ), 55 | ), 56 | ), 57 | ), 58 | SizedBox( 59 | width: 5, 60 | ), 61 | Expanded( 62 | child: ElevatedButton( 63 | onPressed: () { 64 | Navigator.pop(context); 65 | }, 66 | child: Text( 67 | "Cancel", 68 | style: TextStyle( 69 | fontSize: 16, 70 | color: Colors.black, 71 | fontWeight: FontWeight.w700, 72 | ), 73 | ), 74 | style: ElevatedButton.styleFrom( 75 | backgroundColor: Colors.white, 76 | shape: RoundedRectangleBorder( 77 | borderRadius: BorderRadius.circular(12), 78 | ), 79 | ), 80 | ), 81 | ), 82 | ], 83 | ), 84 | ], 85 | ), 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/score_history_section.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_fonts/google_fonts.dart'; 3 | 4 | 5 | 6 | class ScoreHistorySection extends StatefulWidget { 7 | final List blueScores; 8 | final List redScores; 9 | final Size size; 10 | 11 | const ScoreHistorySection({ 12 | Key? key, 13 | required this.blueScores, 14 | required this.redScores, 15 | required this.size, 16 | }) : super(key: key); 17 | 18 | @override 19 | State createState() => _ScoreHistorySectionState(); 20 | } 21 | 22 | class _ScoreHistorySectionState extends State { 23 | @override 24 | Widget build(BuildContext context) { 25 | return Container( 26 | height: widget.size.height * 0.36, 27 | margin: EdgeInsets.symmetric(horizontal: widget.size.width * 0.05), 28 | width: double.infinity, 29 | decoration: BoxDecoration( 30 | color: Colors.black, 31 | borderRadius: BorderRadius.circular(10), 32 | border: Border.all(color: Colors.grey.shade700), 33 | ), 34 | child: Stack( 35 | children: [ 36 | Positioned.fill( 37 | child: Align( 38 | alignment: Alignment.center, 39 | child: Container( 40 | width: 2, 41 | color: Colors.grey, 42 | ), 43 | ), 44 | ), 45 | Padding( 46 | padding: EdgeInsets.only(bottom: widget.size.height * 0.02), 47 | child: Column( 48 | children: [ 49 | Expanded( 50 | child: ListView.builder( 51 | physics: BouncingScrollPhysics(), 52 | itemCount: widget.blueScores.length, 53 | itemBuilder: (context, index) { 54 | return Row( 55 | children: [ 56 | Expanded( 57 | child: Align( 58 | alignment: Alignment.center, 59 | child: Text( 60 | widget.blueScores[index], 61 | style: GoogleFonts.inter( 62 | color: Color(0xff0066FF), 63 | fontSize: 16, 64 | fontWeight: FontWeight.w600, 65 | ), 66 | ), 67 | ), 68 | ), 69 | SizedBox(width: 20), 70 | Expanded( 71 | child: Align( 72 | alignment: Alignment.center, 73 | child: Text( 74 | widget.redScores[index], 75 | style: GoogleFonts.inter( 76 | color: Color(0xffFF4A4A), 77 | fontSize: 16, 78 | fontWeight: FontWeight.w600, 79 | ), 80 | ), 81 | ), 82 | ), 83 | ], 84 | ); 85 | }, 86 | ), 87 | ), 88 | ], 89 | ), 90 | ), 91 | ], 92 | ), 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/features/history_screen/presentation/widgets/history_score_card.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '../../../../shared/models/game_model.dart'; 4 | import '../../../../shared/models/team_model.dart'; 5 | 6 | class HistoryScoreCard extends StatelessWidget { 7 | const HistoryScoreCard({ 8 | super.key, 9 | required this.size, 10 | required this.game, 11 | }); 12 | 13 | final Size size; 14 | final Game game; 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Container( 19 | margin: EdgeInsets.only(bottom: 8), 20 | padding: EdgeInsets.only(left: 24, right: 24), 21 | height: 50, 22 | width: size.width * 0.95, 23 | decoration: BoxDecoration( 24 | color: Color(0xff888888).withOpacity(0.2), 25 | borderRadius: BorderRadius.circular(36), 26 | ), 27 | child: Stack( 28 | children: [ 29 | Container( 30 | height: 50, 31 | child: Row( 32 | children: [ 33 | Container( 34 | width: size.width * 0.32, 35 | child: Row( 36 | crossAxisAlignment: CrossAxisAlignment.center, 37 | children: [ 38 | Text( 39 | game.teamA.name, 40 | style: TextStyle( 41 | color: Colors.blue, 42 | fontSize: 15, 43 | fontWeight: FontWeight.bold), 44 | ), 45 | Spacer(), 46 | Text( 47 | game.teamA.getPoints().toString(), 48 | style: TextStyle( 49 | color: Colors.blue, 50 | fontSize: 15, 51 | fontWeight: FontWeight.bold, 52 | ), 53 | ), 54 | ], 55 | ), 56 | ), 57 | Spacer(), 58 | Container( 59 | width: size.width * 0.32, 60 | child: Row( 61 | crossAxisAlignment: CrossAxisAlignment.center, 62 | children: [ 63 | Text( 64 | game.teamB.getPoints().toString(), 65 | style: TextStyle( 66 | color: Color(0xffFF3B30).withOpacity(0.5), 67 | fontSize: 15, 68 | fontWeight: FontWeight.bold), 69 | ), 70 | Spacer(), 71 | Text( 72 | game.teamB.name, 73 | style: TextStyle( 74 | color: Color(0xffFF3B30).withOpacity(0.5), 75 | fontSize: 15, 76 | fontWeight: FontWeight.bold, 77 | ), 78 | ), 79 | ], 80 | ), 81 | ), 82 | ], 83 | ), 84 | ), 85 | Align( 86 | alignment: Alignment.center, 87 | child: Text( 88 | "vs", 89 | style: TextStyle( 90 | color: Color(0xffFFFFFF).withOpacity(0.4), 91 | fontSize: 20, 92 | ), 93 | ), 94 | ), 95 | ], 96 | ), 97 | ); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/custom_buttons.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/features/history_screen/presentation/widgets/delete_history_dialog.dart'; 2 | import 'package:dominos_notebook/features/home_screen/logic/check_target.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:google_fonts/google_fonts.dart'; 5 | 6 | import '../../../../shared/models/team_model.dart'; 7 | 8 | class CustomRestartButton extends StatefulWidget { 9 | CustomRestartButton({super.key, required this.size, this.onSave}); 10 | 11 | final Size size; 12 | void Function()? onSave; 13 | 14 | @override 15 | State createState() => _CustomRestartButtonState(); 16 | } 17 | 18 | class _CustomRestartButtonState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | return GestureDetector( 22 | onTap: () { 23 | showDialog( 24 | context: context, 25 | builder: (BuildContext context) { 26 | return DeleteHistoryDialog( 27 | onSave: widget.onSave, 28 | ); 29 | }); 30 | }, 31 | child: Container( 32 | padding: EdgeInsets.only(top: 10, bottom: 10), 33 | decoration: BoxDecoration( 34 | color: Color(0xffFFF4A4A).withOpacity(0.2), 35 | borderRadius: BorderRadius.circular(30), 36 | border: Border.all( 37 | color: Color(0xffFF4A4A), 38 | width: 0.8, 39 | ), 40 | ), 41 | child: Row( 42 | mainAxisAlignment: MainAxisAlignment.spaceAround, 43 | mainAxisSize: MainAxisSize.max, 44 | children: [ 45 | SizedBox( 46 | width: widget.size.width * 0.02, 47 | ), 48 | Expanded( 49 | flex: 1, 50 | child: Icon( 51 | Icons.restart_alt_sharp, 52 | color: Color(0xffFF4A4A), 53 | size: 28, 54 | ), 55 | ), 56 | SizedBox( 57 | width: widget.size.width * 0.08, 58 | ), 59 | Expanded( 60 | flex: 5, 61 | child: Text( 62 | "RESTART", 63 | style: GoogleFonts.inter( 64 | color: Color(0xffFFF4A4A), 65 | fontSize: 18, 66 | fontWeight: FontWeight.w700, 67 | ), 68 | ), 69 | ) 70 | ], 71 | ), 72 | ), 73 | ); 74 | } 75 | } 76 | 77 | class CustomUndoButton extends StatelessWidget { 78 | CustomUndoButton({ 79 | super.key, 80 | required this.size, 81 | this.onTap, 82 | }); 83 | 84 | final Size size; 85 | void Function()? onTap; 86 | 87 | @override 88 | Widget build(BuildContext context) { 89 | return GestureDetector( 90 | onTap: onTap, 91 | child: Container( 92 | padding: EdgeInsets.only(top: 10, bottom: 10), 93 | margin: EdgeInsets.symmetric(horizontal: size.width * 0.3), 94 | decoration: BoxDecoration( 95 | color: Color(0xffFFA500).withOpacity(0.2), 96 | borderRadius: BorderRadius.circular(30), 97 | border: Border.all( 98 | color: Color(0xffFFA500), 99 | width: 0.8, 100 | ), 101 | ), 102 | child: Row( 103 | mainAxisAlignment: MainAxisAlignment.center, 104 | mainAxisSize: MainAxisSize.max, 105 | children: [ 106 | Icon( 107 | Icons.undo, 108 | color: Color(0xffFFA500), 109 | size: 24, 110 | ), 111 | SizedBox( 112 | width: 5, 113 | ), 114 | Text( 115 | "UNDO", 116 | style: GoogleFonts.inter( 117 | color: Color(0xffFFA500), 118 | fontSize: 18, 119 | fontWeight: FontWeight.w700, 120 | ), 121 | ) 122 | ], 123 | ), 124 | ), 125 | ); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dominos_notebook 2 | description: "A new Flutter project." 3 | # The following line prevents the package from being accidentally published to 4 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 6 | 7 | # The following defines the version and build number for your application. 8 | # A version number is three numbers separated by dots, like 1.2.43 9 | # followed by an optional build number separated by a +. 10 | # Both the version and the builder number may be overridden in flutter 11 | # build by specifying --build-name and --build-number, respectively. 12 | # In Android, build-name is used as versionName while build-number used as versionCode. 13 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 14 | # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. 15 | # Read more about iOS versioning at 16 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 17 | # In Windows, build-name is used as the major, minor, and patch parts 18 | # of the product and file versions while build-number is used as the build suffix. 19 | version: 1.0.0+1 20 | 21 | environment: 22 | sdk: ^3.6.2 23 | 24 | # Dependencies specify other packages that your package needs in order to work. 25 | # To automatically upgrade your package dependencies to the latest versions 26 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 27 | # dependencies can be manually updated by changing the version numbers below to 28 | # the latest version available on pub.dev. To see which dependencies have newer 29 | # versions available, run `flutter pub outdated`. 30 | dependencies: 31 | flutter: 32 | sdk: flutter 33 | 34 | # The following adds the Cupertino Icons font to your application. 35 | # Use with the CupertinoIcons class for iOS style icons. 36 | cupertino_icons: ^1.0.8 37 | google_fonts: ^6.2.1 38 | hive: ^2.0.0 39 | hive_flutter: ^1.1.0 40 | 41 | 42 | 43 | dev_dependencies: 44 | build_runner: ^2.1.0 45 | hive_generator: ^1.1.0 46 | flutter_launcher_icons: ^0.14.3 47 | flutter_test: 48 | sdk: flutter 49 | 50 | flutter_icons: 51 | android: true 52 | image_path: "assets/logo.png" 53 | 54 | # The "flutter_lints" package below contains a set of recommended lints to 55 | # encourage good coding practices. The lint set provided by the package is 56 | # activated in the `analysis_options.yaml` file located at the root of your 57 | # package. See that file for information about deactivating specific lint 58 | # rules and activating additional ones. 59 | flutter_lints: ^5.0.0 60 | 61 | # For information on the generic Dart part of this file, see the 62 | # following page: https://dart.dev/tools/pub/pubspec 63 | 64 | # The following section is specific to Flutter packages. 65 | flutter: 66 | 67 | # The following line ensures that the Material Icons font is 68 | # included with your application, so that you can use the icons in 69 | # the material Icons class. 70 | uses-material-design: true 71 | 72 | # To add assets to your application, add an assets section, like this: 73 | # assets: 74 | # - images/a_dot_burr.jpeg 75 | # - images/a_dot_ham.jpeg 76 | 77 | # An image asset can refer to one or more resolution-specific "variants", see 78 | # https://flutter.dev/to/resolution-aware-images 79 | 80 | # For details regarding adding assets from package dependencies, see 81 | # https://flutter.dev/to/asset-from-package 82 | 83 | # To add custom fonts to your application, add a fonts section here, 84 | # in this "flutter" section. Each entry in this list should have a 85 | # "family" key with the font family name, and a "fonts" key with a 86 | # list giving the asset and other descriptors for the font. For 87 | # example: 88 | # fonts: 89 | # - family: Schyler 90 | # fonts: 91 | # - asset: fonts/Schyler-Regular.ttf 92 | # - asset: fonts/Schyler-Italic.ttf 93 | # style: italic 94 | # - family: Trajan Pro 95 | # fonts: 96 | # - asset: fonts/TrajanPro.ttf 97 | # - asset: fonts/TrajanPro_Bold.ttf 98 | # weight: 700 99 | # 100 | # For details regarding fonts from package dependencies, 101 | # see https://flutter.dev/to/font-from-package 102 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/edit_name_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class EditNameDialog extends StatelessWidget { 4 | EditNameDialog({ 5 | super.key, 6 | this.onSave, 7 | this.title = "EDIT NAME", 8 | this.onChanged, 9 | required this.controller, 10 | required this.formKey, 11 | }); 12 | VoidCallback? onSave; 13 | Function(String)? onChanged; 14 | String title; 15 | TextEditingController controller; 16 | GlobalKey formKey; 17 | @override 18 | Widget build(BuildContext context) { 19 | var media = MediaQuery.sizeOf(context); 20 | return AlertDialog( 21 | backgroundColor: const Color.fromARGB(255, 0, 8, 15), 22 | title: Center( 23 | child: Text( 24 | title, 25 | style: TextStyle( 26 | color: Colors.white, 27 | fontWeight: FontWeight.w600, 28 | fontSize: 20, 29 | ), 30 | ), 31 | ), 32 | content: Form( 33 | key: formKey, 34 | child: Column( 35 | mainAxisSize: MainAxisSize.min, 36 | crossAxisAlignment: CrossAxisAlignment.start, 37 | children: [ 38 | Container( 39 | decoration: BoxDecoration( 40 | color: Colors.black, borderRadius: BorderRadius.circular(12)), 41 | child: Container( 42 | padding: EdgeInsets.zero, 43 | width: media.width * 0.9, 44 | child: TextFormField( 45 | validator: (text) { 46 | if (text != null) { 47 | if (text.isNotEmpty) { 48 | if (text.length > 12) { 49 | return "Name length is between 1 and 11"; 50 | } 51 | } else { 52 | return 'Please insert a valid name'; 53 | } 54 | } else { 55 | return 'Please insert a valid name'; 56 | } 57 | }, 58 | controller: controller, 59 | onChanged: onChanged, 60 | style: TextStyle(color: Colors.white, fontSize: 20), 61 | autofocus: true, 62 | decoration: InputDecoration( 63 | contentPadding: EdgeInsets.only(left: 12), 64 | border: InputBorder.none, 65 | focusedBorder: InputBorder.none, 66 | enabledBorder: InputBorder.none, 67 | errorBorder: InputBorder.none, 68 | disabledBorder: InputBorder.none, 69 | ), 70 | ), 71 | ), 72 | ), 73 | SizedBox( 74 | height: 10, 75 | ), 76 | Row( 77 | mainAxisSize: MainAxisSize.min, 78 | children: [ 79 | Expanded( 80 | child: ElevatedButton( 81 | onPressed: () { 82 | if (formKey.currentState!.validate()) { 83 | onSave!(); 84 | Navigator.pop(context); 85 | controller.clear(); 86 | } 87 | }, 88 | child: const Text( 89 | "Save", 90 | style: TextStyle( 91 | color: Colors.white, 92 | fontSize: 16, 93 | fontWeight: FontWeight.w700, 94 | ), 95 | ), 96 | style: ElevatedButton.styleFrom( 97 | backgroundColor: Colors.black, 98 | shape: RoundedRectangleBorder( 99 | borderRadius: BorderRadius.circular(12), 100 | ), 101 | ), 102 | ), 103 | ), 104 | SizedBox( 105 | width: 5, 106 | ), 107 | Expanded( 108 | child: ElevatedButton( 109 | onPressed: () { 110 | Navigator.pop(context); 111 | }, 112 | child: Text( 113 | "Cancel", 114 | style: TextStyle( 115 | fontSize: 16, 116 | color: Colors.red, 117 | fontWeight: FontWeight.w700, 118 | ), 119 | ), 120 | style: ElevatedButton.styleFrom( 121 | backgroundColor: Colors.white, 122 | shape: RoundedRectangleBorder( 123 | borderRadius: BorderRadius.circular(12), 124 | ), 125 | ), 126 | ), 127 | ), 128 | ], 129 | ), 130 | ], 131 | ), 132 | ), 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/features/history_screen/presentation/history_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/core/constants.dart'; 2 | import 'package:dominos_notebook/features/history_screen/logic/hive_history.dart'; 3 | import 'package:dominos_notebook/features/history_screen/presentation/widgets/delete_history_dialog.dart'; 4 | import 'package:dominos_notebook/features/history_screen/presentation/widgets/history_score_card.dart'; 5 | import 'package:dominos_notebook/features/home_screen/logic/reset_history.dart'; 6 | import 'package:dominos_notebook/shared/models/team_model.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:google_fonts/google_fonts.dart'; 9 | import 'package:hive_flutter/hive_flutter.dart'; 10 | 11 | import '../../../shared/models/game_model.dart'; 12 | 13 | class MatchHistoryScreen extends StatefulWidget { 14 | MatchHistoryScreen({super.key}); 15 | 16 | @override 17 | State createState() => _MatchHistoryScreenState(); 18 | } 19 | 20 | class _MatchHistoryScreenState extends State { 21 | Box mainbox = Hive.box("dominos"); 22 | late List games; 23 | @override 24 | void initState() { 25 | // TODO: implement initState 26 | super.initState(); 27 | games = readHistory(mainbox); 28 | print(games); 29 | } 30 | 31 | void resetHistoryState() { 32 | setState(() { 33 | resetHistory(); 34 | games = []; 35 | }); 36 | } 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | var size = MediaQuery.of(context).size; 41 | return Scaffold( 42 | backgroundColor: Colors.black, 43 | appBar: HistoryScreenAppBar(size, context, resetHistoryState), 44 | body: Center( 45 | child: games.length != 0 46 | ? ListView.builder( 47 | itemCount: games.length, 48 | itemBuilder: (context, index) { 49 | return HistoryScoreCard( 50 | size: size, 51 | game: games[index], 52 | ); 53 | }) 54 | : Text( 55 | "Play games to fill the history!", 56 | style: TextStyle( 57 | color: Colors.white, 58 | fontSize: 26, 59 | fontWeight: FontWeight.w600, 60 | ), 61 | )), 62 | ); 63 | } 64 | 65 | PreferredSize HistoryScreenAppBar( 66 | Size size, BuildContext context, void Function()? onSave) { 67 | return PreferredSize( 68 | preferredSize: Size.fromHeight(size.height * 0.2), 69 | child: Container( 70 | padding: EdgeInsets.symmetric(vertical: 20), 71 | child: SafeArea( 72 | child: Container( 73 | decoration: BoxDecoration( 74 | color: Color(0xff4A4A4A).withOpacity(0.2), 75 | ), 76 | child: Row( 77 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 78 | children: [ 79 | IconButton( 80 | icon: Container( 81 | padding: EdgeInsets.all(8), 82 | decoration: BoxDecoration( 83 | color: Color(0xffD9D9D9).withOpacity(0.25), 84 | shape: BoxShape.circle, 85 | ), 86 | child: Icon( 87 | Icons.arrow_back_ios, 88 | color: Colors.white, 89 | size: 26, 90 | ), 91 | ), 92 | onPressed: () => Navigator.of(context).pop(), 93 | ), 94 | Text( 95 | "Match History", 96 | style: GoogleFonts.inter( 97 | color: Colors.white, 98 | fontWeight: FontWeight.w700, 99 | fontSize: 25, 100 | ), 101 | ), 102 | IconButton( 103 | icon: Container( 104 | padding: EdgeInsets.all(8), 105 | decoration: BoxDecoration( 106 | color: Color(0xffD9D9D9).withOpacity(0.25), 107 | shape: BoxShape.circle, 108 | ), 109 | child: Icon(Icons.delete_rounded, 110 | color: Colors.red.withOpacity(0.9), size: 27), 111 | ), 112 | onPressed: () { 113 | showDialog( 114 | context: context, 115 | builder: (BuildContext context) { 116 | return DeleteHistoryDialog( 117 | onSave: onSave, 118 | // () { 119 | // setState(() { 120 | // resetHistory(); 121 | // historyGames = []; 122 | // }); 123 | // }, 124 | ); 125 | }); 126 | }, 127 | ), 128 | ], 129 | ), 130 | ), 131 | ), 132 | ), 133 | ); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/add_points_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AddPointsDialog extends StatelessWidget { 4 | AddPointsDialog({ 5 | super.key, 6 | this.onSave, 7 | this.title = "ADD POINTS", 8 | this.onChanged, 9 | required this.controller, 10 | required this.formKey, 11 | }); 12 | 13 | final VoidCallback? onSave; 14 | final Function(String)? onChanged; 15 | final String title; 16 | final TextEditingController controller; 17 | final GlobalKey formKey; 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | var media = MediaQuery.sizeOf(context); 22 | return AlertDialog( 23 | backgroundColor: const Color.fromARGB(255, 0, 8, 15), 24 | title: Center( 25 | child: Text( 26 | title, 27 | style: const TextStyle( 28 | color: Colors.white, 29 | fontWeight: FontWeight.w600, 30 | fontSize: 20, 31 | ), 32 | ), 33 | ), 34 | content: Form( 35 | key: formKey, 36 | child: Column( 37 | mainAxisSize: MainAxisSize.min, 38 | crossAxisAlignment: CrossAxisAlignment.start, 39 | children: [ 40 | Container( 41 | decoration: BoxDecoration( 42 | color: Colors.black, 43 | borderRadius: BorderRadius.circular(12), 44 | ), 45 | child: Container( 46 | padding: EdgeInsets.zero, 47 | width: media.width * 0.9, 48 | child: TextFormField( 49 | controller: controller, 50 | onChanged: onChanged, 51 | validator: (text) { 52 | if (text == null || text.isEmpty) { 53 | return 'Please insert a number'; 54 | } 55 | if (int.tryParse(text) == null) { 56 | return 'Please insert a valid number'; 57 | } 58 | if (int.parse(text) > 100) { 59 | return 'Points can not be higher than 100'; 60 | } 61 | return null; 62 | }, 63 | style: const TextStyle( 64 | color: Colors.white, 65 | fontSize: 20, 66 | ), 67 | autofocus: true, 68 | keyboardType: TextInputType.number, 69 | decoration: const InputDecoration( 70 | contentPadding: EdgeInsets.only(left: 12), 71 | border: InputBorder.none, 72 | focusedBorder: InputBorder.none, 73 | enabledBorder: InputBorder.none, 74 | errorBorder: InputBorder.none, 75 | disabledBorder: InputBorder.none, 76 | ), 77 | ), 78 | ), 79 | ), 80 | const SizedBox(height: 10), 81 | Row( 82 | mainAxisSize: MainAxisSize.min, 83 | children: [ 84 | Expanded( 85 | child: ElevatedButton( 86 | onPressed: () { 87 | if (formKey.currentState!.validate()) { 88 | onSave?.call(); 89 | if (Navigator.canPop(context)) { 90 | Navigator.pop(context); 91 | } 92 | controller.clear(); 93 | } 94 | }, 95 | style: ElevatedButton.styleFrom( 96 | backgroundColor: Colors.black, 97 | shape: RoundedRectangleBorder( 98 | borderRadius: BorderRadius.circular(12), 99 | ), 100 | ), 101 | child: const Text( 102 | "Save", 103 | style: TextStyle( 104 | color: Colors.white, 105 | fontSize: 16, 106 | fontWeight: FontWeight.w700, 107 | ), 108 | ), 109 | ), 110 | ), 111 | const SizedBox(width: 5), 112 | Expanded( 113 | child: ElevatedButton( 114 | onPressed: () { 115 | if (Navigator.canPop(context)) { 116 | Navigator.pop(context); 117 | } 118 | }, 119 | style: ElevatedButton.styleFrom( 120 | backgroundColor: Colors.white, 121 | shape: RoundedRectangleBorder( 122 | borderRadius: BorderRadius.circular(12), 123 | ), 124 | ), 125 | child: const Text( 126 | "Cancel", 127 | style: TextStyle( 128 | fontSize: 16, 129 | color: Colors.red, 130 | fontWeight: FontWeight.w700, 131 | ), 132 | ), 133 | ), 134 | ), 135 | ], 136 | ), 137 | ], 138 | ), 139 | ), 140 | ); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/widgets/custom_team_score.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/features/home_screen/logic/hive_functions.dart'; 2 | import 'package:dominos_notebook/features/home_screen/presentation/widgets/edit_name_dialog.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:google_fonts/google_fonts.dart'; 5 | import 'package:hive_flutter/hive_flutter.dart'; 6 | 7 | import '../../../../shared/models/team_model.dart'; 8 | 9 | class CustomTeamScore extends StatefulWidget { 10 | CustomTeamScore({ 11 | super.key, 12 | required this.size, 13 | required this.currentTeam, 14 | required this.opponentTeam, 15 | required this.teamColor, 16 | required this.onAddPoints, 17 | required this.currentTeamNameController, 18 | required this.box, 19 | }); 20 | 21 | final Size size; 22 | final Team currentTeam; 23 | final Team opponentTeam; 24 | final MaterialColor teamColor; 25 | final Function(int) onAddPoints; 26 | final TextEditingController currentTeamNameController; 27 | 28 | final Box box; 29 | 30 | @override 31 | State createState() => _CustomTeamScoreState(); 32 | } 33 | 34 | class _CustomTeamScoreState extends State { 35 | final GlobalKey blueformKey = GlobalKey(); 36 | final GlobalKey redformKey = GlobalKey(); 37 | late GlobalKey formKey; 38 | @override 39 | void initState() { 40 | // TODO: implement initState 41 | super.initState(); 42 | if (widget.teamColor == Colors.blue) { 43 | formKey = blueformKey; 44 | print("form1"); 45 | } else { 46 | formKey = redformKey; 47 | print('form2'); 48 | } 49 | } 50 | 51 | @override 52 | Widget build(BuildContext context) { 53 | return Column( 54 | children: [ 55 | Container( 56 | height: 120, 57 | width: 154, 58 | decoration: BoxDecoration( 59 | border: Border.all( 60 | width: 3, 61 | color: widget.teamColor.withOpacity(0.2), 62 | ), 63 | borderRadius: BorderRadius.circular( 64 | 16, 65 | ), 66 | ), 67 | child: Form( 68 | key: formKey, 69 | child: Column( 70 | mainAxisAlignment: MainAxisAlignment.center, 71 | children: [ 72 | GestureDetector( 73 | onTap: () { 74 | showDialog( 75 | context: context, 76 | builder: (BuildContext context) { 77 | return EditNameDialog( 78 | formKey: GlobalKey(), 79 | controller: widget.currentTeamNameController, 80 | onSave: () { 81 | 82 | try { 83 | setState(() { 84 | widget.currentTeam.name = 85 | widget.currentTeamNameController.text; 86 | if (widget.teamColor == Colors.blue) { 87 | writeTeamA( 88 | widget.box, widget.currentTeam); 89 | writeTeamB( 90 | widget.box, widget.opponentTeam); 91 | } else { 92 | writeTeamB( 93 | widget.box, widget.currentTeam); 94 | writeTeamA( 95 | widget.box, widget.opponentTeam); 96 | } 97 | }); 98 | } catch (e, stackTrace) { 99 | print('Error: $e'); 100 | print('StackTrace: $stackTrace'); 101 | } 102 | 103 | }); 104 | }); 105 | }, 106 | child: Row( 107 | mainAxisAlignment: MainAxisAlignment.center, 108 | children: [ 109 | Text( 110 | widget.currentTeam.name, 111 | style: GoogleFonts.inter( 112 | color: widget.teamColor, 113 | fontWeight: FontWeight.w600, 114 | fontSize: 16, 115 | ), 116 | ), 117 | SizedBox( 118 | width: widget.size.width * 0.02, 119 | ), 120 | Icon( 121 | Icons.edit, 122 | color: Colors.white, 123 | size: 12, 124 | ) 125 | ], 126 | ), 127 | ), 128 | Text( 129 | widget.currentTeam.getPoints().toString(), 130 | style: GoogleFonts.inter( 131 | color: Colors.white, 132 | fontSize: 48, 133 | fontWeight: FontWeight.w600, 134 | ), 135 | ), 136 | ], 137 | ), 138 | ), 139 | ), 140 | SizedBox( 141 | height: 5, 142 | ), 143 | Container( 144 | height: 50, 145 | width: 50, 146 | decoration: BoxDecoration( 147 | color: widget.teamColor.withOpacity(0.2), 148 | borderRadius: BorderRadius.circular(360), 149 | ), 150 | child: IconButton( 151 | icon: Icon( 152 | Icons.add_circle, 153 | color: widget.teamColor, 154 | size: 35, 155 | ), 156 | onPressed: () { 157 | widget.onAddPoints(10); 158 | }, 159 | ), 160 | ) 161 | ], 162 | ); 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /lib/features/home_screen/presentation/home_screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:dominos_notebook/features/home_screen/logic/check_target.dart'; 2 | import 'package:dominos_notebook/features/home_screen/logic/hive_functions.dart'; 3 | import 'package:dominos_notebook/features/home_screen/presentation/widgets/custom_buttons.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:google_fonts/google_fonts.dart'; 6 | import 'package:hive_flutter/hive_flutter.dart'; 7 | 8 | import '../../../shared/models/team_model.dart'; 9 | import 'widgets/add_points_dialog.dart'; 10 | import 'widgets/app_footer.dart'; 11 | import 'widgets/custom_app_bar.dart'; 12 | import 'widgets/custom_score_goal_widget.dart'; 13 | import 'widgets/custom_team_score.dart'; 14 | import 'widgets/score_history_section.dart'; 15 | 16 | class HomeScreen extends StatefulWidget { 17 | HomeScreen({super.key}); 18 | 19 | @override 20 | State createState() => _HomeScreenState(); 21 | } 22 | 23 | class _HomeScreenState extends State { 24 | late Team blueTeam; 25 | 26 | late Team redTeam; 27 | var mainbox = Hive.box("dominos"); 28 | String lastAddedTeam = "none"; 29 | int targetScore = 100; 30 | 31 | TextEditingController blueTeamController = TextEditingController(); 32 | TextEditingController redTeamController = TextEditingController(); 33 | TextEditingController redTeamNameController = TextEditingController(); 34 | TextEditingController blueTeamNameController = TextEditingController(); 35 | final GlobalKey formKey = GlobalKey(); 36 | void addPoints(Team team, Team opponent, int points) { 37 | setState(() { 38 | team.addPoints(points); 39 | team.addGamePoints(points.toString()); 40 | opponent.addGamePoints("-"); 41 | }); 42 | } 43 | 44 | Team? readTeamA(Box box) { 45 | return box.get("TeamA"); 46 | } 47 | 48 | Team? readTeamB(Box box) { 49 | return box.get("TeamB"); 50 | } 51 | 52 | @override 53 | void initState() { 54 | super.initState(); 55 | blueTeam = readTeamA(mainbox) ?? Team(name: "Blue Team"); 56 | print(blueTeam.getGamePoints()); 57 | redTeam = readTeamB(mainbox) ?? Team(name: "Red Team"); 58 | print(redTeam.getGamePoints()); 59 | Future.delayed(Duration.zero, () { 60 | precacheDialog(context); 61 | }); 62 | } 63 | 64 | void precacheDialog(BuildContext context) { 65 | OverlayEntry overlayEntry = OverlayEntry( 66 | builder: (context) => Offstage( 67 | offstage: true, 68 | child: AddPointsDialog( 69 | formKey: GlobalKey(), 70 | controller: TextEditingController(), 71 | onSave: () {}, 72 | ), 73 | ), 74 | ); 75 | Overlay.of(context).insert(overlayEntry); 76 | Future.delayed(const Duration(milliseconds: 50), () { 77 | overlayEntry.remove(); 78 | }); 79 | } 80 | 81 | @override 82 | Widget build(BuildContext context) { 83 | var size = MediaQuery.of(context).size; 84 | return Scaffold( 85 | backgroundColor: Colors.black, 86 | body: SingleChildScrollView( 87 | child: Padding( 88 | padding: EdgeInsets.only( 89 | top: size.height * 0.05, 90 | right: size.width * 0.03, 91 | left: size.width * 0.03, 92 | bottom: size.height * 0.05, 93 | ), 94 | child: Column( 95 | children: [ 96 | CustomAppBar( 97 | size: size, 98 | title: "DOMINO", 99 | ), 100 | SizedBox( 101 | height: 15, 102 | ), 103 | Center( 104 | child: Column( 105 | mainAxisAlignment: MainAxisAlignment.center, 106 | crossAxisAlignment: CrossAxisAlignment.start, 107 | children: [ 108 | Row( 109 | children: [ 110 | SizedBox( 111 | width: size.width * 0.03, 112 | ), 113 | CustomScoreGoalWidget( 114 | goalScore: targetScore, 115 | ), 116 | ], 117 | ), 118 | SizedBox(height: 10), 119 | Row( 120 | mainAxisAlignment: MainAxisAlignment.spaceAround, 121 | crossAxisAlignment: CrossAxisAlignment.start, 122 | children: [ 123 | Column( 124 | children: [ 125 | CustomTeamScore( 126 | box: mainbox, 127 | size: size, 128 | currentTeam: blueTeam, 129 | opponentTeam: redTeam, 130 | teamColor: Colors.blue, 131 | currentTeamNameController: 132 | blueTeamNameController, 133 | onAddPoints: (points) { 134 | showDialog( 135 | context: context, 136 | builder: (BuildContext context) { 137 | return AddPointsDialog( 138 | formKey:GlobalKey(), 139 | controller: blueTeamController, 140 | onSave: () { 141 | if (blueTeamController 142 | .text.isNotEmpty) { 143 | setState(() { 144 | blueTeam.addGamePoints( 145 | blueTeamController.text); 146 | redTeam.addGamePoints("0"); 147 | 148 | if (checkTarget(blueTeam, 149 | redTeam, targetScore)) { 150 | setState(() { 151 | ResetGame( 152 | blueTeam, redTeam); 153 | lastAddedTeam = "none"; 154 | }); 155 | } 156 | lastAddedTeam = "blue"; 157 | writeTeamA(mainbox, blueTeam); 158 | writeTeamB(mainbox, redTeam); 159 | }); 160 | } 161 | }, 162 | ); 163 | }); 164 | }, 165 | ), 166 | SizedBox( 167 | height: 5, 168 | ), 169 | ], 170 | ), 171 | CustomTeamScore( 172 | teamColor: Colors.red, 173 | box: mainbox, 174 | size: size, 175 | currentTeam: redTeam, 176 | opponentTeam: blueTeam, 177 | currentTeamNameController: redTeamNameController, 178 | onAddPoints: (points) { 179 | showDialog( 180 | context: context, 181 | builder: (BuildContext context) { 182 | return AddPointsDialog( 183 | formKey: GlobalKey(), 184 | controller: redTeamController, 185 | onSave: () { 186 | if (redTeamController.text.isNotEmpty) { 187 | setState(() { 188 | redTeam.addGamePoints( 189 | redTeamController.text); 190 | blueTeam.addGamePoints("0"); 191 | if (checkTarget(blueTeam, redTeam, 192 | targetScore)) { 193 | setState(() { 194 | ResetGame(blueTeam, redTeam); 195 | lastAddedTeam = "none"; 196 | }); 197 | } 198 | lastAddedTeam = "red"; 199 | writeTeamA(mainbox, blueTeam); 200 | writeTeamB(mainbox, redTeam); 201 | }); 202 | } 203 | }, 204 | ); 205 | }); 206 | }, 207 | ), 208 | ], 209 | ), 210 | ], 211 | ), 212 | ), 213 | SizedBox( 214 | height: 10, 215 | ), 216 | ScoreHistorySection( 217 | blueScores: blueTeam.getGamePoints(), 218 | redScores: redTeam.getGamePoints(), 219 | size: size, 220 | ), 221 | SizedBox( 222 | height: 25, 223 | ), 224 | Center( 225 | child: CustomUndoButton( 226 | size: size, 227 | onTap: () { 228 | if (blueTeam.getGamePoints().isNotEmpty || 229 | redTeam.getGamePoints().isNotEmpty) { 230 | setState(() { 231 | blueTeam.undoPoint(); 232 | redTeam.undoPoint(); 233 | writeTeamA(mainbox, blueTeam); 234 | writeTeamB(mainbox, redTeam); 235 | }); 236 | } 237 | }, 238 | ), 239 | ), 240 | SizedBox( 241 | height: 20, 242 | ), 243 | AppFooter( 244 | size: size, 245 | onSave: () { 246 | setState(() { 247 | ResetGame(blueTeam, redTeam); 248 | }); 249 | }, 250 | ), 251 | ], 252 | ), 253 | ), 254 | ), 255 | ); 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | sha256: "4897882604d919befd350648c7f91926a9d5de99e67b455bf0917cc2362f4bb8" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "47.0.0" 12 | analyzer: 13 | dependency: transitive 14 | description: 15 | name: analyzer 16 | sha256: "690e335554a8385bc9d787117d9eb52c0c03ee207a607e593de3c9d71b1cfe80" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "4.7.0" 20 | archive: 21 | dependency: transitive 22 | description: 23 | name: archive 24 | sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "4.0.7" 28 | args: 29 | dependency: transitive 30 | description: 31 | name: args 32 | sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.7.0" 36 | async: 37 | dependency: transitive 38 | description: 39 | name: async 40 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "2.11.0" 44 | boolean_selector: 45 | dependency: transitive 46 | description: 47 | name: boolean_selector 48 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "2.1.1" 52 | build: 53 | dependency: transitive 54 | description: 55 | name: build 56 | sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "2.4.1" 60 | build_config: 61 | dependency: transitive 62 | description: 63 | name: build_config 64 | sha256: "4ae2de3e1e67ea270081eaee972e1bd8f027d459f249e0f1186730784c2e7e33" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "1.1.2" 68 | build_daemon: 69 | dependency: transitive 70 | description: 71 | name: build_daemon 72 | sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "4.0.4" 76 | build_resolvers: 77 | dependency: transitive 78 | description: 79 | name: build_resolvers 80 | sha256: "687cf90a3951affac1bd5f9ecb5e3e90b60487f3d9cdc359bb310f8876bb02a6" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "2.0.10" 84 | build_runner: 85 | dependency: "direct dev" 86 | description: 87 | name: build_runner 88 | sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "2.4.13" 92 | build_runner_core: 93 | dependency: transitive 94 | description: 95 | name: build_runner_core 96 | sha256: "6d6ee4276b1c5f34f21fdf39425202712d2be82019983d52f351c94aafbc2c41" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "7.2.10" 100 | built_collection: 101 | dependency: transitive 102 | description: 103 | name: built_collection 104 | sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "5.1.1" 108 | built_value: 109 | dependency: transitive 110 | description: 111 | name: built_value 112 | sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "8.9.5" 116 | characters: 117 | dependency: transitive 118 | description: 119 | name: characters 120 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "1.3.0" 124 | checked_yaml: 125 | dependency: transitive 126 | description: 127 | name: checked_yaml 128 | sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "2.0.3" 132 | cli_util: 133 | dependency: transitive 134 | description: 135 | name: cli_util 136 | sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "0.4.2" 140 | clock: 141 | dependency: transitive 142 | description: 143 | name: clock 144 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "1.1.1" 148 | code_builder: 149 | dependency: transitive 150 | description: 151 | name: code_builder 152 | sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "4.10.1" 156 | collection: 157 | dependency: transitive 158 | description: 159 | name: collection 160 | sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "1.19.0" 164 | convert: 165 | dependency: transitive 166 | description: 167 | name: convert 168 | sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "3.1.2" 172 | crypto: 173 | dependency: transitive 174 | description: 175 | name: crypto 176 | sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "3.0.6" 180 | cupertino_icons: 181 | dependency: "direct main" 182 | description: 183 | name: cupertino_icons 184 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "1.0.8" 188 | dart_style: 189 | dependency: transitive 190 | description: 191 | name: dart_style 192 | sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4" 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "2.2.4" 196 | fake_async: 197 | dependency: transitive 198 | description: 199 | name: fake_async 200 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "1.3.1" 204 | ffi: 205 | dependency: transitive 206 | description: 207 | name: ffi 208 | sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "2.1.3" 212 | file: 213 | dependency: transitive 214 | description: 215 | name: file 216 | sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 217 | url: "https://pub.dev" 218 | source: hosted 219 | version: "7.0.1" 220 | fixnum: 221 | dependency: transitive 222 | description: 223 | name: fixnum 224 | sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be 225 | url: "https://pub.dev" 226 | source: hosted 227 | version: "1.1.1" 228 | flutter: 229 | dependency: "direct main" 230 | description: flutter 231 | source: sdk 232 | version: "0.0.0" 233 | flutter_launcher_icons: 234 | dependency: "direct dev" 235 | description: 236 | name: flutter_launcher_icons 237 | sha256: bfa04787c85d80ecb3f8777bde5fc10c3de809240c48fa061a2c2bf15ea5211c 238 | url: "https://pub.dev" 239 | source: hosted 240 | version: "0.14.3" 241 | flutter_test: 242 | dependency: "direct dev" 243 | description: flutter 244 | source: sdk 245 | version: "0.0.0" 246 | frontend_server_client: 247 | dependency: transitive 248 | description: 249 | name: frontend_server_client 250 | sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 251 | url: "https://pub.dev" 252 | source: hosted 253 | version: "4.0.0" 254 | glob: 255 | dependency: transitive 256 | description: 257 | name: glob 258 | sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de 259 | url: "https://pub.dev" 260 | source: hosted 261 | version: "2.1.3" 262 | google_fonts: 263 | dependency: "direct main" 264 | description: 265 | name: google_fonts 266 | sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82 267 | url: "https://pub.dev" 268 | source: hosted 269 | version: "6.2.1" 270 | graphs: 271 | dependency: transitive 272 | description: 273 | name: graphs 274 | sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" 275 | url: "https://pub.dev" 276 | source: hosted 277 | version: "2.3.2" 278 | hive: 279 | dependency: "direct main" 280 | description: 281 | name: hive 282 | sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" 283 | url: "https://pub.dev" 284 | source: hosted 285 | version: "2.2.3" 286 | hive_flutter: 287 | dependency: "direct main" 288 | description: 289 | name: hive_flutter 290 | sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc 291 | url: "https://pub.dev" 292 | source: hosted 293 | version: "1.1.0" 294 | hive_generator: 295 | dependency: "direct dev" 296 | description: 297 | name: hive_generator 298 | sha256: "81fd20125cb2ce8fd23623d7744ffbaf653aae93706c9bd3bf7019ea0ace3938" 299 | url: "https://pub.dev" 300 | source: hosted 301 | version: "1.1.3" 302 | http: 303 | dependency: transitive 304 | description: 305 | name: http 306 | sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f 307 | url: "https://pub.dev" 308 | source: hosted 309 | version: "1.3.0" 310 | http_multi_server: 311 | dependency: transitive 312 | description: 313 | name: http_multi_server 314 | sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 315 | url: "https://pub.dev" 316 | source: hosted 317 | version: "3.2.2" 318 | http_parser: 319 | dependency: transitive 320 | description: 321 | name: http_parser 322 | sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" 323 | url: "https://pub.dev" 324 | source: hosted 325 | version: "4.1.2" 326 | image: 327 | dependency: transitive 328 | description: 329 | name: image 330 | sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" 331 | url: "https://pub.dev" 332 | source: hosted 333 | version: "4.5.4" 334 | io: 335 | dependency: transitive 336 | description: 337 | name: io 338 | sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b 339 | url: "https://pub.dev" 340 | source: hosted 341 | version: "1.0.5" 342 | js: 343 | dependency: transitive 344 | description: 345 | name: js 346 | sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf 347 | url: "https://pub.dev" 348 | source: hosted 349 | version: "0.7.1" 350 | json_annotation: 351 | dependency: transitive 352 | description: 353 | name: json_annotation 354 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" 355 | url: "https://pub.dev" 356 | source: hosted 357 | version: "4.9.0" 358 | leak_tracker: 359 | dependency: transitive 360 | description: 361 | name: leak_tracker 362 | sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" 363 | url: "https://pub.dev" 364 | source: hosted 365 | version: "10.0.7" 366 | leak_tracker_flutter_testing: 367 | dependency: transitive 368 | description: 369 | name: leak_tracker_flutter_testing 370 | sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" 371 | url: "https://pub.dev" 372 | source: hosted 373 | version: "3.0.8" 374 | leak_tracker_testing: 375 | dependency: transitive 376 | description: 377 | name: leak_tracker_testing 378 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 379 | url: "https://pub.dev" 380 | source: hosted 381 | version: "3.0.1" 382 | logging: 383 | dependency: transitive 384 | description: 385 | name: logging 386 | sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 387 | url: "https://pub.dev" 388 | source: hosted 389 | version: "1.3.0" 390 | matcher: 391 | dependency: transitive 392 | description: 393 | name: matcher 394 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 395 | url: "https://pub.dev" 396 | source: hosted 397 | version: "0.12.16+1" 398 | material_color_utilities: 399 | dependency: transitive 400 | description: 401 | name: material_color_utilities 402 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 403 | url: "https://pub.dev" 404 | source: hosted 405 | version: "0.11.1" 406 | meta: 407 | dependency: transitive 408 | description: 409 | name: meta 410 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 411 | url: "https://pub.dev" 412 | source: hosted 413 | version: "1.15.0" 414 | mime: 415 | dependency: transitive 416 | description: 417 | name: mime 418 | sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" 419 | url: "https://pub.dev" 420 | source: hosted 421 | version: "2.0.0" 422 | package_config: 423 | dependency: transitive 424 | description: 425 | name: package_config 426 | sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc 427 | url: "https://pub.dev" 428 | source: hosted 429 | version: "2.2.0" 430 | path: 431 | dependency: transitive 432 | description: 433 | name: path 434 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 435 | url: "https://pub.dev" 436 | source: hosted 437 | version: "1.9.0" 438 | path_provider: 439 | dependency: transitive 440 | description: 441 | name: path_provider 442 | sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" 443 | url: "https://pub.dev" 444 | source: hosted 445 | version: "2.1.5" 446 | path_provider_android: 447 | dependency: transitive 448 | description: 449 | name: path_provider_android 450 | sha256: "0ca7359dad67fd7063cb2892ab0c0737b2daafd807cf1acecd62374c8fae6c12" 451 | url: "https://pub.dev" 452 | source: hosted 453 | version: "2.2.16" 454 | path_provider_foundation: 455 | dependency: transitive 456 | description: 457 | name: path_provider_foundation 458 | sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" 459 | url: "https://pub.dev" 460 | source: hosted 461 | version: "2.4.1" 462 | path_provider_linux: 463 | dependency: transitive 464 | description: 465 | name: path_provider_linux 466 | sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 467 | url: "https://pub.dev" 468 | source: hosted 469 | version: "2.2.1" 470 | path_provider_platform_interface: 471 | dependency: transitive 472 | description: 473 | name: path_provider_platform_interface 474 | sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" 475 | url: "https://pub.dev" 476 | source: hosted 477 | version: "2.1.2" 478 | path_provider_windows: 479 | dependency: transitive 480 | description: 481 | name: path_provider_windows 482 | sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 483 | url: "https://pub.dev" 484 | source: hosted 485 | version: "2.3.0" 486 | petitparser: 487 | dependency: transitive 488 | description: 489 | name: petitparser 490 | sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 491 | url: "https://pub.dev" 492 | source: hosted 493 | version: "6.0.2" 494 | platform: 495 | dependency: transitive 496 | description: 497 | name: platform 498 | sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" 499 | url: "https://pub.dev" 500 | source: hosted 501 | version: "3.1.6" 502 | plugin_platform_interface: 503 | dependency: transitive 504 | description: 505 | name: plugin_platform_interface 506 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 507 | url: "https://pub.dev" 508 | source: hosted 509 | version: "2.1.8" 510 | pool: 511 | dependency: transitive 512 | description: 513 | name: pool 514 | sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" 515 | url: "https://pub.dev" 516 | source: hosted 517 | version: "1.5.1" 518 | posix: 519 | dependency: transitive 520 | description: 521 | name: posix 522 | sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62 523 | url: "https://pub.dev" 524 | source: hosted 525 | version: "6.0.2" 526 | pub_semver: 527 | dependency: transitive 528 | description: 529 | name: pub_semver 530 | sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" 531 | url: "https://pub.dev" 532 | source: hosted 533 | version: "2.2.0" 534 | pubspec_parse: 535 | dependency: transitive 536 | description: 537 | name: pubspec_parse 538 | sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" 539 | url: "https://pub.dev" 540 | source: hosted 541 | version: "1.5.0" 542 | shelf: 543 | dependency: transitive 544 | description: 545 | name: shelf 546 | sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 547 | url: "https://pub.dev" 548 | source: hosted 549 | version: "1.4.2" 550 | shelf_web_socket: 551 | dependency: transitive 552 | description: 553 | name: shelf_web_socket 554 | sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67 555 | url: "https://pub.dev" 556 | source: hosted 557 | version: "2.0.1" 558 | sky_engine: 559 | dependency: transitive 560 | description: flutter 561 | source: sdk 562 | version: "0.0.0" 563 | source_gen: 564 | dependency: transitive 565 | description: 566 | name: source_gen 567 | sha256: "2d79738b6bbf38a43920e2b8d189e9a3ce6cc201f4b8fc76be5e4fe377b1c38d" 568 | url: "https://pub.dev" 569 | source: hosted 570 | version: "1.2.6" 571 | source_helper: 572 | dependency: transitive 573 | description: 574 | name: source_helper 575 | sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f" 576 | url: "https://pub.dev" 577 | source: hosted 578 | version: "1.3.3" 579 | source_span: 580 | dependency: transitive 581 | description: 582 | name: source_span 583 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 584 | url: "https://pub.dev" 585 | source: hosted 586 | version: "1.10.0" 587 | stack_trace: 588 | dependency: transitive 589 | description: 590 | name: stack_trace 591 | sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" 592 | url: "https://pub.dev" 593 | source: hosted 594 | version: "1.12.0" 595 | stream_channel: 596 | dependency: transitive 597 | description: 598 | name: stream_channel 599 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 600 | url: "https://pub.dev" 601 | source: hosted 602 | version: "2.1.2" 603 | stream_transform: 604 | dependency: transitive 605 | description: 606 | name: stream_transform 607 | sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 608 | url: "https://pub.dev" 609 | source: hosted 610 | version: "2.1.1" 611 | string_scanner: 612 | dependency: transitive 613 | description: 614 | name: string_scanner 615 | sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" 616 | url: "https://pub.dev" 617 | source: hosted 618 | version: "1.3.0" 619 | term_glyph: 620 | dependency: transitive 621 | description: 622 | name: term_glyph 623 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 624 | url: "https://pub.dev" 625 | source: hosted 626 | version: "1.2.1" 627 | test_api: 628 | dependency: transitive 629 | description: 630 | name: test_api 631 | sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" 632 | url: "https://pub.dev" 633 | source: hosted 634 | version: "0.7.3" 635 | timing: 636 | dependency: transitive 637 | description: 638 | name: timing 639 | sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" 640 | url: "https://pub.dev" 641 | source: hosted 642 | version: "1.0.2" 643 | typed_data: 644 | dependency: transitive 645 | description: 646 | name: typed_data 647 | sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 648 | url: "https://pub.dev" 649 | source: hosted 650 | version: "1.4.0" 651 | vector_math: 652 | dependency: transitive 653 | description: 654 | name: vector_math 655 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 656 | url: "https://pub.dev" 657 | source: hosted 658 | version: "2.1.4" 659 | vm_service: 660 | dependency: transitive 661 | description: 662 | name: vm_service 663 | sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b 664 | url: "https://pub.dev" 665 | source: hosted 666 | version: "14.3.0" 667 | watcher: 668 | dependency: transitive 669 | description: 670 | name: watcher 671 | sha256: "69da27e49efa56a15f8afe8f4438c4ec02eff0a117df1b22ea4aad194fe1c104" 672 | url: "https://pub.dev" 673 | source: hosted 674 | version: "1.1.1" 675 | web: 676 | dependency: transitive 677 | description: 678 | name: web 679 | sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" 680 | url: "https://pub.dev" 681 | source: hosted 682 | version: "1.1.1" 683 | web_socket: 684 | dependency: transitive 685 | description: 686 | name: web_socket 687 | sha256: bfe6f435f6ec49cb6c01da1e275ae4228719e59a6b067048c51e72d9d63bcc4b 688 | url: "https://pub.dev" 689 | source: hosted 690 | version: "1.0.0" 691 | web_socket_channel: 692 | dependency: transitive 693 | description: 694 | name: web_socket_channel 695 | sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 696 | url: "https://pub.dev" 697 | source: hosted 698 | version: "3.0.3" 699 | xdg_directories: 700 | dependency: transitive 701 | description: 702 | name: xdg_directories 703 | sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" 704 | url: "https://pub.dev" 705 | source: hosted 706 | version: "1.1.0" 707 | xml: 708 | dependency: transitive 709 | description: 710 | name: xml 711 | sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 712 | url: "https://pub.dev" 713 | source: hosted 714 | version: "6.5.0" 715 | yaml: 716 | dependency: transitive 717 | description: 718 | name: yaml 719 | sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce 720 | url: "https://pub.dev" 721 | source: hosted 722 | version: "3.1.3" 723 | sdks: 724 | dart: ">=3.6.2 <4.0.0" 725 | flutter: ">=3.27.0" 726 | --------------------------------------------------------------------------------