diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c5f3f6b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index e50c3a0..f7eb7f6 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/lib/main.dart b/lib/main.dart index dcfeffb..4f9f83f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,15 +1,22 @@ import 'package:flutter/material.dart'; import 'package:werwolf/screens/playerregistry.dart'; +import 'package:werwolf/theme/theme.dart'; void main() { - runApp(MaterialApp( - // theme: ThemeData.dark(), - theme: ThemeData( - colorScheme: ColorScheme.fromSwatch() - .copyWith(primary: const Color.fromARGB(255, 29, 29, 29)), - scaffoldBackgroundColor: Colors.grey[800], - ), - darkTheme: ThemeData.dark(), - home: const PlayerRegistry(), - )); + runApp( + const MyApp(), + ); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: halloweenTheme, + home: PlayerRegistry(), + debugShowCheckedModeBanner: false, + ); + } } diff --git a/lib/models/game.dart b/lib/models/game.dart index 410dd06..dcceec0 100644 --- a/lib/models/game.dart +++ b/lib/models/game.dart @@ -49,7 +49,8 @@ class Game { } randomRoles.shuffle(); for (var playerName in playernames) { - players.add(Player(name: playerName, role: randomRoles.last)); + players + .add(Player(name: playerName, role: randomRoles.last, isDead: false)); randomRoles.removeLast(); } return players; diff --git a/lib/models/player.dart b/lib/models/player.dart index 3d3b16b..2aaddcd 100644 --- a/lib/models/player.dart +++ b/lib/models/player.dart @@ -3,6 +3,7 @@ import 'package:werwolf/models/role.dart'; class Player { String name; Role role; + bool isDead; - Player({required this.name, required this.role}); + Player({required this.name, required this.role, required this.isDead}); } diff --git a/lib/screens/flippingcards.dart b/lib/screens/flippingcards.dart index c84ac75..f62cf23 100644 --- a/lib/screens/flippingcards.dart +++ b/lib/screens/flippingcards.dart @@ -1,6 +1,8 @@ import 'package:flip_card/flip_card_controller.dart'; import 'package:flutter/material.dart'; import 'package:flip_card/flip_card.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:werwolf/screens/gameboard.dart'; import '../models/player.dart'; import '../models/role.dart'; @@ -37,29 +39,26 @@ class _FlipingCardState extends State { speed: 300, onFlipDone: (status) {}, front: Container( - decoration: const BoxDecoration( - color: Color(0xFF006666), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primary, borderRadius: BorderRadius.all(Radius.circular(8.0)), ), child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( padding: const EdgeInsets.all(10), child: Text( widget.players[index].name, + style: Theme.of(context).textTheme.headlineMedium, textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .displayMedium - ?.copyWith(color: Colors.white), ), ), - Text('Klick um deine Rolle zu sehen!', - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyLarge?.copyWith( - color: const Color.fromARGB(255, 202, 202, 202))), + Text( + 'Klick um deine Rolle zu sehen!', + textAlign: TextAlign.center, + ), ], ), ), @@ -67,22 +66,19 @@ class _FlipingCardState extends State { decoration: BoxDecoration( color: widget.players[index].role != Role.werwolf ? const Color(0xFF006666) - : Color.fromARGB(255, 100, 21, 15), + : const Color.fromARGB(255, 100, 21, 15), borderRadius: const BorderRadius.all(Radius.circular(8.0)), ), child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, + crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Container( padding: const EdgeInsets.all(10), child: Text( widget.players[index].role.stringValue, + style: Theme.of(context).textTheme.headlineMedium, textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .displaySmall - ?.copyWith(color: Colors.white), ), ), ], @@ -98,6 +94,12 @@ class _FlipingCardState extends State { appBar: AppBar( title: const Text("Werwolf"), centerTitle: true, + leading: IconButton( + icon: const Icon(FontAwesomeIcons.xmark), + onPressed: () { + Navigator.popUntil(context, ModalRoute.withName('/')); + }, + ), ), body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -105,18 +107,12 @@ class _FlipingCardState extends State { children: [ Expanded(child: _renderContent(context)), Container( - color: const Color.fromARGB(255, 29, 29, 29), + padding: EdgeInsets.only(bottom: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ OutlinedButton( - style: OutlinedButton.styleFrom( - foregroundColor: Colors.red, - side: const BorderSide( - color: Colors.red, - ), - ), onPressed: () { setState(() { if (index > 0 && index <= widget.players.length) { @@ -129,13 +125,7 @@ class _FlipingCardState extends State { }, child: const Text("Zurück"), ), - OutlinedButton( - style: OutlinedButton.styleFrom( - foregroundColor: const Color.fromARGB(255, 40, 168, 168), - side: const BorderSide( - color: Color.fromARGB(255, 40, 168, 168), - ), - ), + ElevatedButton( onPressed: () { setState(() { if (index >= 0 && index < widget.players.length - 1) { @@ -143,10 +133,20 @@ class _FlipingCardState extends State { if (!_controller.state!.isFront) { _controller.toggleCardWithoutAnimation(); } + } else if (index == widget.players.length - 1) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + PlayerGridView(players: widget.players), + ), + ); } }); }, - child: const Text("Nächster Spieler"), + child: Text(index != widget.players.length - 1 + ? "Nächster Spieler" + : "Spiel anfangen!"), ), ], ), diff --git a/lib/screens/gameboard.dart b/lib/screens/gameboard.dart new file mode 100644 index 0000000..0b5136a --- /dev/null +++ b/lib/screens/gameboard.dart @@ -0,0 +1,225 @@ +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import '../models/player.dart'; +import '../models/role.dart'; + +class PlayerGridView extends StatefulWidget { + final List players; + + const PlayerGridView({required this.players, Key? key}) : super(key: key); + + @override + _PlayerGridViewState createState() => _PlayerGridViewState(); +} + +class _PlayerGridViewState extends State { + bool isNight = true; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + isNight ? Icons.nights_stay : Icons.wb_sunny, + size: 24, + color: isNight ? Colors.grey[300] : Colors.yellow, + ), + SizedBox(width: 10), + Text( + isNight ? 'Nacht' : 'Tag', + ), + ], + ), + centerTitle: true, + actions: [ + IconButton( + icon: Icon(Icons.info), + onPressed: () { + _showRolesDialog(); + }, + ), + ], + leading: IconButton( + icon: const Icon(FontAwesomeIcons.xmark), + onPressed: () { + Navigator.popUntil(context, ModalRoute.withName('/')); + }, + ), + ), + body: Container( + color: isNight + ? const Color(0xff2d2d2d) + : const Color.fromARGB(255, 178, 203, 214), + padding: const EdgeInsets.only(left: 15, right: 15), + child: Column( + children: [ + Expanded( + child: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + ), + itemCount: widget.players.length, + itemBuilder: (context, index) { + widget.players[index]; + + return GestureDetector( + onTap: () { + setState(() { + if (!widget.players[index].isDead) { + _killPlayer(widget.players[index]); + } + }); + }, + child: Card( + color: widget.players[index].isDead + ? Colors.grey + : Theme.of(context).colorScheme.primary, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + widget.players[index].name, + style: TextStyle(fontSize: 24), + textAlign: TextAlign.center, + maxLines: 3, + overflow: TextOverflow.ellipsis, + ), + if (widget.players[index].isDead) + Icon(Icons.close, color: Colors.red, size: 48), + ], + ), + ), + ); + }, + ), + ), + Divider( + height: 1, + color: Colors.grey, + ), + Padding( + padding: EdgeInsets.only(bottom: 15, top: 15), + child: ElevatedButton( + onPressed: _changePhase, + child: Text(isNight ? 'Tag skippen' : 'Nacht skippen'), + ), + ), + ], + ), + ), + ); + } + + void _killPlayer(Player player) { + if (isNight) { + if (player.role != Role.werwolf) { + player.isDead = true; + _checkWinCondition(); + isNight = false; + } + } else { + player.isDead = true; + _checkWinCondition(); + if (player.role == Role.joker) { + _showWinDialog('Der Joker hat gewonnen!'); + } + isNight = true; + } + setState(() {}); + } + + void _changePhase() { + if (isNight) { + isNight = false; + } else { + isNight = true; + } + setState(() {}); + } + + void _checkWinCondition() { + int countWolves = widget.players + .where((player) => !player.isDead && player.role == Role.werwolf) + .length; + int countVillagers = widget.players + .where((player) => !player.isDead && player.role != Role.werwolf) + .length; + + if (countWolves == 0) { + _showWinDialog('Die Dorfbewohner haben gewonnen!'); + } else if (countWolves >= countVillagers) { + _showWinDialog('Die Werwölfe haben gewonnen!'); + } + } + + void _showWinDialog(String message) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Spielende'), + content: Text(message), + actions: [ + TextButton( + child: Text('Spiel beenden'), + onPressed: () { + Navigator.popUntil(context, ModalRoute.withName('/')); + }, + ), + ], + ); + }, + ); + } + + void _showRolesDialog() { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Spielerrollen'), + content: Container( + width: double.maxFinite, + child: ListView.builder( + shrinkWrap: true, + itemCount: widget.players.length, + itemBuilder: (context, index) { + final player = widget.players[index]; + return ListTile( + title: Text( + player.name, + style: Theme.of(context).textTheme.labelLarge, + ), + subtitle: Text( + player.role.name, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + ), + ), + ); + }, + ), + ), + actions: [ + TextButton( + child: Text('OK'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + } +} diff --git a/lib/screens/playerregistry.dart b/lib/screens/playerregistry.dart index 1cf39ad..729af9c 100644 --- a/lib/screens/playerregistry.dart +++ b/lib/screens/playerregistry.dart @@ -21,74 +21,91 @@ class _PlayerRegistryState extends State { title: const Text("Werwolf"), centerTitle: true, ), - body: Column( - children: [ - TextField( - key: _formKey, - controller: _playerController, - decoration: InputDecoration( - errorText: _errorMessage == "" ? null : _errorMessage, - labelText: 'Spielername', - labelStyle: const TextStyle( - color: Colors.white, + body: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(15), + child: TextField( + key: _formKey, + controller: _playerController, + decoration: InputDecoration( + errorText: _errorMessage == "" ? null : _errorMessage, + labelText: 'Spielername', + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.primary), + ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.secondary), + ), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Theme.of(context).colorScheme.secondary), + ), + ), + onSubmitted: (value) { + setState(() { + if (_playerController.text.isEmpty) { + _errorMessage = "Spielername ist leer!"; + } else if (playernames.contains(value)) { + _errorMessage = "Dieser Spieler existiert bereits"; + _playerController.clear(); + } else { + _errorMessage = ""; + _playerController.clear(); + playernames.add(value); + } + }); + }, ), ), - style: const TextStyle(color: Colors.white), - onSubmitted: (value) { - setState(() { - if (_playerController.text.isEmpty) { - _errorMessage = "Spielername ist leer!"; - } else if (playernames.contains(value)) { - _errorMessage = "Dieser Spieler existiert bereits"; - _playerController.clear(); - } else { - _errorMessage = ""; - _playerController.clear(); - playernames.add(value); - } - }); - }, - ), - Expanded( - child: ListView.builder( - itemCount: playernames.length, - itemBuilder: (context, index) { - return ListTile( - title: Text( - playernames[index], - style: const TextStyle(color: Colors.white), - ), - tileColor: Colors.grey, - trailing: IconButton( - onPressed: () { - setState(() { - playernames.remove(playernames[index]); - }); - }, - icon: const Icon(Icons.remove, color: Colors.white)), - ); - }, + Expanded( + child: ListView.builder( + itemCount: playernames.length, + itemBuilder: (context, index) { + return ListTile( + title: Text( + playernames[index], + ), + trailing: IconButton( + onPressed: () { + setState(() { + playernames.remove(playernames[index]); + }); + }, + icon: const Icon(Icons.remove)), + ); + }, + ), ), - ), - ElevatedButton( - onPressed: () { - if (playernames.length >= 6) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => GameSettings( - playernames: playernames, - ), - )); - } else { - setState(() { - _errorMessage = "Es müssen mindestens 6 Spieler sein!"; - }); - } - }, - child: const Text('Spiel einstellen'), - ), - ], + ElevatedButton( + onPressed: () { + if (playernames.length >= 6) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GameSettings( + playernames: playernames, + ), + )); + } else { + setState(() { + _errorMessage = "Es müssen mindestens 6 Spieler sein!"; + }); + } + }, + child: const Text('Spiel einstellen'), + ), + Padding(padding: EdgeInsets.all(30)) + ], + ), ), ); } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 5bcbe3c..e381784 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:werwolf/screens/flippingcards.dart'; import '../models/game.dart'; @@ -14,6 +15,7 @@ class GameSettings extends StatefulWidget { class _GameSettingsState extends State { late Game game; + @override void initState() { game = Game(playernames: widget.playernames); @@ -24,20 +26,28 @@ class _GameSettingsState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text("Werwolf"), + title: Text( + "Werwolf", + style: Theme.of(context).textTheme.titleLarge, // Apply text theme + ), centerTitle: true, + leading: IconButton( + icon: const Icon(FontAwesomeIcons.xmark), + onPressed: () { + Navigator.popUntil(context, ModalRoute.withName('/')); + }, + ), ), body: Padding( padding: const EdgeInsets.fromLTRB(30.0, 40.0, 30.0, 0.0), child: Column( children: [ Text( - "Anzahl der Spieler ${widget.playernames.length}", // hier muss noch die anzahl der spieler hin - style: const TextStyle(color: Colors.white, fontSize: 18), + "Anzahl der Spieler ${widget.playernames.length}", + style: Theme.of(context).textTheme.titleLarge, // Apply text theme ), const Divider( height: 60, - color: Colors.grey, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -45,31 +55,37 @@ class _GameSettingsState extends State { children: [ Text( "Anzahl der Werwölfe ${game.getWolves()}", - style: const TextStyle(color: Colors.white, fontSize: 18), + style: + Theme.of(context).textTheme.bodyLarge, // Apply text theme ), IconButton( - onPressed: () { - setState(() { - game.decrementWolves(); - }); - }, - icon: const Icon(Icons.remove, color: Colors.white)), + onPressed: () { + setState(() { + game.decrementWolves(); + }); + }, + icon: const Icon(Icons.remove, color: Colors.white), + ), IconButton( - onPressed: () { - setState(() { - game.incrementWolves(); - }); - }, - icon: const Icon(Icons.add, color: Colors.white)), + onPressed: () { + setState(() { + game.incrementWolves(); + }); + }, + icon: const Icon(Icons.add, color: Colors.white), + ), ], ), const Divider( height: 60, - color: Colors.grey, ), - const Text( - "Spezielle Rollen", - style: TextStyle(color: Colors.white, fontSize: 18), + Padding( + padding: const EdgeInsets.only(top: 8.0, bottom: 20), + child: Text( + "Spezielle Rollen", + style: + Theme.of(context).textTheme.titleLarge, // Apply text theme + ), ), Expanded( child: ListView.builder( @@ -81,20 +97,18 @@ class _GameSettingsState extends State { return ListTile( title: Text( role.stringValue, - style: - const TextStyle(color: Colors.white, fontSize: 16), + style: Theme.of(context) + .textTheme + .bodyLarge, // Apply text theme ), trailing: Switch( - value: game.specialRoles[role], - trackColor: const MaterialStatePropertyAll( - Color.fromARGB(255, 189, 189, 189)), - thumbColor: const MaterialStatePropertyAll( - Colors.black), - onChanged: (bool value) { - setState(() { - game.specialRoles[role] = value; - }); - }), + value: game.specialRoles[role], + onChanged: (bool value) { + setState(() { + game.specialRoles[role] = value; + }); + }, + ), ); } return Container(); @@ -104,14 +118,18 @@ class _GameSettingsState extends State { ElevatedButton( onPressed: () { Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - FlipingCard(players: game.getAllPlayers()), - )); + context, + MaterialPageRoute( + builder: (context) => + FlipingCard(players: game.getAllPlayers()), + ), + ); }, - child: const Text('Spiel starten!'), + child: Text( + 'Spiel starten!', + ), ), + const Padding(padding: EdgeInsets.all(30)), ], ), ), diff --git a/lib/theme/theme.dart b/lib/theme/theme.dart new file mode 100644 index 0000000..30622f9 --- /dev/null +++ b/lib/theme/theme.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; + +ThemeData halloweenTheme = ThemeData( + useMaterial3: true, + brightness: Brightness.dark, + colorScheme: ColorScheme.dark( + surface: const Color(0xff2d2d2d), // Dark grey for a spooky base + primary: const Color(0xffff7518), // Halloween orange + secondary: const Color(0xff8b0000), // Deep red for a sinister touch + tertiary: Colors.black, // Black for an eerie contrast + ), + scaffoldBackgroundColor: const Color(0xff2d2d2d), // Match the surface color + elevatedButtonTheme: ElevatedButtonThemeData( + style: ButtonStyle( + backgroundColor: WidgetStateProperty.all( + const Color(0xffff7518), // Halloween orange + ), + foregroundColor: WidgetStateProperty.all( + Colors.black, // Text color to contrast with button background + ), + ), + ), + iconTheme: const IconThemeData( + color: Color(0xffff7518), // Halloween orange + ), + chipTheme: ChipThemeData( + backgroundColor: const Color(0xff8b0000), // Deep red + selectedColor: const Color(0xffff7518), // Halloween orange + labelStyle: TextStyle( + color: Colors.white, // Text color for better readability + ), + ), + sliderTheme: SliderThemeData( + activeTickMarkColor: const Color(0xffff7518), // Halloween orange + activeTrackColor: const Color(0xffff7518), // Halloween orange + thumbColor: const Color(0xffff7518), // Halloween orange + valueIndicatorTextStyle: TextStyle( + color: Colors.black, // Text color for the value indicator + ), + ), + dividerTheme: DividerThemeData( + color: Colors.white, // Halloween orange + thickness: 1.0, // Set the thickness of the divider + ), + textTheme: TextTheme( + displayLarge: TextStyle( + color: Colors.white, // Halloween orange + fontSize: 32.0, + fontWeight: FontWeight.bold, + ), + displayMedium: TextStyle( + color: Colors.white, // Deep red + fontSize: 28.0, + fontWeight: FontWeight.bold, + ), + displaySmall: TextStyle( + color: Colors.white, // White for contrast + fontSize: 24.0, + fontWeight: FontWeight.bold, + ), + bodyLarge: TextStyle( + color: Colors.white, // Halloween orange + fontSize: 16.0, + ), + bodyMedium: TextStyle( + color: Colors.white, // White for contrast + fontSize: 14.0, + ), + bodySmall: TextStyle( + color: Colors.white, // Deep red + fontSize: 12.0, + ), + labelLarge: TextStyle( + color: Colors.white, // Black for contrast + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), +); diff --git a/pubspec.lock b/pubspec.lock index 522cf7a..9276e5f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" boolean_selector: dependency: transitive description: @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" fake_async: dependency: transitive description: @@ -75,54 +75,78 @@ packages: description: flutter source: sdk version: "0.0.0" - js: - dependency: transitive + font_awesome_flutter: + dependency: "direct main" description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + name: font_awesome_flutter + sha256: "275ff26905134bcb59417cf60ad979136f1f8257f2f449914b2c3e05bbb4cd6f" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "10.7.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + url: "https://pub.dev" + source: hosted + version: "10.0.5" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + url: "https://pub.dev" + source: hosted + version: "3.0.5" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.1" matcher: dependency: transitive description: name: matcher - sha256: c94db23593b89766cda57aab9ac311e3616cf87c6fa4e9749df032f66f30dcb8 + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.14" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "12307e7f0605ce3da64cf0db90e5fcab0869f3ca03f76be6bb2991ce0a55e82b" + sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.14.0" path: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" sky_engine: dependency: transitive description: flutter @@ -132,26 +156,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -172,10 +196,10 @@ packages: dependency: transitive description: name: test_api - sha256: "6182294da5abf431177fccc1ee02401f6df30f766bc6130a0852c6b6d7ee6b2d" + sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794" url: "https://pub.dev" source: hosted - version: "0.4.18" + version: "0.7.1" vector_math: dependency: transitive description: @@ -184,5 +208,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b" + url: "https://pub.dev" + source: hosted + version: "14.2.2" sdks: - dart: ">=3.0.0-313.0.dev <4.0.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 4f987e8..e82d505 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: flip_card: ^0.7.0 + font_awesome_flutter: ^10.7.0 flutter: sdk: flutter