From 0f7508ecf7c50b5c7c26f67dc1e486cea6ec63b9 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 24 Apr 2021 22:19:26 +0300 Subject: [PATCH 01/24] Flutter BLoC --- team_c_f/pubspec.lock | 14 ++++++++++++++ team_c_f/pubspec.yaml | 1 + 2 files changed, 15 insertions(+) diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index 330d35c..ed59328 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.5.0" + bloc: + dependency: transitive + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.0" boolean_selector: dependency: transitive description: @@ -174,6 +181,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.0" flutter_test: dependency: "direct dev" description: flutter diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index df6b702..e70416a 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -41,6 +41,7 @@ dependencies: fluttertoast: ^8.0.3 adaptive_dialog: ^0.10.0+5 onesignal_flutter: ^2.6.3 + flutter_bloc: ^7.0.0 dev_dependencies: flutter_test: From fd7e456a4b159cb8d858a97e59ba75189f21703a Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sun, 25 Apr 2021 20:37:46 +0300 Subject: [PATCH 02/24] Mobx --- team_c_f/pubspec.lock | 165 +++++++++++++++++++++++++++++++++++++++--- team_c_f/pubspec.yaml | 5 +- 2 files changed, 160 insertions(+), 10 deletions(-) diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index ed59328..9e67e3d 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "21.0.0" adaptive_dialog: dependency: "direct main" description: @@ -8,6 +15,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.10.0+5" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" animations: dependency: transitive description: @@ -15,20 +29,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" - async: + args: dependency: transitive description: - name: async + name: args url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" - bloc: + version: "2.1.0" + async: dependency: transitive description: - name: bloc + name: async url: "https://pub.dartlang.org" source: hosted - version: "7.0.0" + version: "2.5.0" boolean_selector: dependency: transitive description: @@ -36,6 +50,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" carousel_slider: dependency: "direct main" description: @@ -57,6 +85,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" clock: dependency: transitive description: @@ -92,6 +127,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" csslib: dependency: transitive description: @@ -120,6 +169,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" date_range_picker: dependency: "direct main" description: @@ -134,6 +190,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.0" firebase_auth: dependency: "direct main" description: @@ -181,13 +244,13 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_bloc: + flutter_mobx: dependency: "direct main" description: - name: flutter_bloc + name: flutter_mobx url: "https://pub.dartlang.org" source: hosted - version: "7.0.0" + version: "2.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -205,6 +268,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "8.0.3" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" google_sign_in: dependency: "direct main" description: @@ -226,6 +296,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.10.0" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" html: dependency: "direct main" description: @@ -261,6 +338,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.3" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" matcher: dependency: transitive description: @@ -275,6 +359,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + mobx: + dependency: "direct main" + description: + name: mobx + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + mobx_codegen: + dependency: "direct dev" + description: + name: mobx_codegen + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1+3" nested: dependency: transitive description: @@ -289,6 +387,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.6.3" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" path: dependency: transitive description: @@ -310,6 +415,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" provider: dependency: "direct main" description: @@ -317,6 +429,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" quiver: dependency: transitive description: @@ -329,6 +448,13 @@ packages: description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" source_span: dependency: transitive description: @@ -350,6 +476,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" string_scanner: dependency: transitive description: @@ -385,6 +518,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" sdks: dart: ">=2.12.0 <3.0.0" flutter: ">=1.20.0" diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index e70416a..a0a2c62 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -41,9 +41,12 @@ dependencies: fluttertoast: ^8.0.3 adaptive_dialog: ^0.10.0+5 onesignal_flutter: ^2.6.3 - flutter_bloc: ^7.0.0 + mobx: ^2.0.1 + flutter_mobx: ^2.0.0 dev_dependencies: + mobx_codegen: ^2.0.1+3 + flutter_test: sdk: flutter From 2de824891c7482ae0a911121928363c1b9446cef Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 26 Apr 2021 17:57:05 +0300 Subject: [PATCH 03/24] sbk up to 2.12 --- .vscode/tasks.json | 15 + team_c_f/lib/components/login.dart | 93 ++++++ team_c_f/lib/components/selectteam.dart | 205 ++++++++++++ team_c_f/lib/data/singledata/login.dart | 11 + team_c_f/lib/element/player.dart | 48 --- team_c_f/lib/main.dart | 313 +----------------- team_c_f/lib/{ => old}/data/currenttour.dart | 8 +- team_c_f/lib/{ => old}/data/data.dart | 22 +- team_c_f/lib/{ => old}/data/forecast.dart | 19 +- team_c_f/lib/{ => old}/data/match.dart | 16 +- team_c_f/lib/{ => old}/data/player.dart | 18 +- team_c_f/lib/{ => old}/data/push.dart | 13 +- team_c_f/lib/{ => old}/data/schedule.dart | 21 +- team_c_f/lib/{ => old}/data/shortmatch.dart | 12 +- team_c_f/lib/{ => old}/data/team.dart | 10 +- team_c_f/lib/{ => old}/data/tournament.dart | 54 +-- .../lib/{ => old}/element/createschedule.dart | 8 +- team_c_f/lib/{ => old}/element/forecast.dart | 18 +- team_c_f/lib/{ => old}/element/match.dart | 4 +- team_c_f/lib/{ => old}/element/meet.dart | 2 +- .../{ => old}/element/notconfirmedplayer.dart | 6 +- team_c_f/lib/old/element/player.dart | 51 +++ team_c_f/lib/{ => old}/element/schedule.dart | 8 +- .../lib/{ => old}/element/selectTeam.dart | 14 +- team_c_f/lib/{ => old}/element/team.dart | 10 +- team_c_f/lib/{ => old}/element/tour.dart | 56 ++-- team_c_f/lib/old/oldmain.dart | 85 +++++ team_c_f/lib/{ => old}/page/home.dart | 20 +- .../lib/{ => old}/page/leaveforecast.dart | 8 +- team_c_f/lib/{ => old}/page/selectmatch.dart | 8 +- team_c_f/lib/{ => old}/page/sign.dart | 6 +- team_c_f/lib/{ => old}/servise/auth.dart | 8 +- team_c_f/lib/{ => old}/servise/htmlparse.dart | 7 +- team_c_f/lib/{ => old}/servise/make.dart | 21 +- .../lib/{ => old}/servise/operationdb.dart | 53 ++- team_c_f/lib/{ => old}/view/day.dart | 10 +- .../lib/{ => old}/view/emptyschedule.dart | 10 +- team_c_f/lib/{ => old}/view/forecast.dart | 2 +- team_c_f/lib/{ => old}/view/match.dart | 8 +- team_c_f/lib/{ => old}/view/meet.dart | 0 team_c_f/lib/{ => old}/view/schedule.dart | 6 +- team_c_f/lib/{ => old}/view/scorers.dart | 2 +- team_c_f/lib/{ => old}/view/table.dart | 2 +- team_c_f/lib/{ => old}/view/team.dart | 18 +- team_c_f/lib/{ => old}/view/tournament.dart | 10 +- team_c_f/lib/pages/login.dart | 97 ++++++ team_c_f/lib/store/login/login.dart | 80 +++++ team_c_f/lib/store/login/login.g.dart | 112 +++++++ team_c_f/pubspec.lock | 153 ++++++++- team_c_f/pubspec.yaml | 6 +- 50 files changed, 1163 insertions(+), 624 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 team_c_f/lib/components/login.dart create mode 100644 team_c_f/lib/components/selectteam.dart create mode 100644 team_c_f/lib/data/singledata/login.dart delete mode 100644 team_c_f/lib/element/player.dart rename team_c_f/lib/{ => old}/data/currenttour.dart (58%) rename team_c_f/lib/{ => old}/data/data.dart (59%) rename team_c_f/lib/{ => old}/data/forecast.dart (75%) rename team_c_f/lib/{ => old}/data/match.dart (78%) rename team_c_f/lib/{ => old}/data/player.dart (74%) rename team_c_f/lib/{ => old}/data/push.dart (75%) rename team_c_f/lib/{ => old}/data/schedule.dart (80%) rename team_c_f/lib/{ => old}/data/shortmatch.dart (81%) rename team_c_f/lib/{ => old}/data/team.dart (79%) rename team_c_f/lib/{ => old}/data/tournament.dart (85%) rename team_c_f/lib/{ => old}/element/createschedule.dart (95%) rename team_c_f/lib/{ => old}/element/forecast.dart (94%) rename team_c_f/lib/{ => old}/element/match.dart (95%) rename team_c_f/lib/{ => old}/element/meet.dart (86%) rename team_c_f/lib/{ => old}/element/notconfirmedplayer.dart (91%) create mode 100644 team_c_f/lib/old/element/player.dart rename team_c_f/lib/{ => old}/element/schedule.dart (87%) rename team_c_f/lib/{ => old}/element/selectTeam.dart (96%) rename team_c_f/lib/{ => old}/element/team.dart (84%) rename team_c_f/lib/{ => old}/element/tour.dart (79%) create mode 100644 team_c_f/lib/old/oldmain.dart rename team_c_f/lib/{ => old}/page/home.dart (86%) rename team_c_f/lib/{ => old}/page/leaveforecast.dart (88%) rename team_c_f/lib/{ => old}/page/selectmatch.dart (94%) rename team_c_f/lib/{ => old}/page/sign.dart (95%) rename team_c_f/lib/{ => old}/servise/auth.dart (74%) rename team_c_f/lib/{ => old}/servise/htmlparse.dart (90%) rename team_c_f/lib/{ => old}/servise/make.dart (86%) rename team_c_f/lib/{ => old}/servise/operationdb.dart (84%) rename team_c_f/lib/{ => old}/view/day.dart (93%) rename team_c_f/lib/{ => old}/view/emptyschedule.dart (81%) rename team_c_f/lib/{ => old}/view/forecast.dart (86%) rename team_c_f/lib/{ => old}/view/match.dart (87%) rename team_c_f/lib/{ => old}/view/meet.dart (100%) rename team_c_f/lib/{ => old}/view/schedule.dart (86%) rename team_c_f/lib/{ => old}/view/scorers.dart (85%) rename team_c_f/lib/{ => old}/view/table.dart (91%) rename team_c_f/lib/{ => old}/view/team.dart (88%) rename team_c_f/lib/{ => old}/view/tournament.dart (92%) create mode 100644 team_c_f/lib/pages/login.dart create mode 100644 team_c_f/lib/store/login/login.dart create mode 100644 team_c_f/lib/store/login/login.g.dart diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..2f0f891 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "dart", + "command": "dart", + "args": [ + "pub", + "get" + ], + "problemMatcher": [], + "label": "dart: dart pub get" + } + ] +} \ No newline at end of file diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart new file mode 100644 index 0000000..088cbdf --- /dev/null +++ b/team_c_f/lib/components/login.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/components/selectteam.dart'; +import 'package:team_c_f/data/singledata/login.dart'; +import 'package:team_c_f/store/login/login.dart'; + +class LoginView extends StatelessWidget { + @override + Widget build(BuildContext context) { + final Login login = context.read().login!; + return Container( + height: double.infinity, + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Observer( + builder: (_) => ElevatedButton( + onPressed: () { + login.updatedLoginStatus + ? login.logoutAccount() + : login.googleLogin(); + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + login.updatedLoginStatus ? 'Выйти' : 'Войти', + ), + SizedBox(width: 10), + Image( + image: AssetImage('assets/images/google.png'), + fit: BoxFit.fill, + height: 30, + ), + ], + ), + ), + ), + Observer( + builder: (_) => Text( + login.updatedLoginStatus + ? 'Вход выполнен, осталось совсем чуть чуть' + : 'Необходимо войти в аккаунт', + textAlign: TextAlign.center, + ), + ), + SizedBox( + height: 20, + ), + Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(16.0), + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Введите ваше имя и фамилию', + style: TextStyle( + color: Colors.white, + ), + ), + ), + TextField( + // Ввод имени участника + decoration: InputDecoration( + fillColor: Colors.white, + filled: true, + ), + onChanged: login.changeName, + textAlign: TextAlign.center, + ), + ], + ), + ), + Observer( + builder: (_) => SelectTeam( + message: 'Зарегистрироваться', + name: login.userName, + ), + ), + ], + ), + ); + } +} diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart new file mode 100644 index 0000000..9dc9973 --- /dev/null +++ b/team_c_f/lib/components/selectteam.dart @@ -0,0 +1,205 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/data/singledata/login.dart'; +import 'package:team_c_f/store/login/login.dart'; + +class SelectTeam extends StatefulWidget { + // Класс отображения выбора команды или регистрации новой + final String message; + final String name; + SelectTeam({Key? key, required this.message, required this.name}) : super(key: key); + + @override + _SelectTeamState createState() => _SelectTeamState(); +} + +class _SelectTeamState extends State { + TextEditingController teamController = TextEditingController(); + String? teamSelect; + bool capitan = false; + + @override + Widget build(BuildContext context) { + final Login? login = context.read().login; + return Column( + children: [ + Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(16.0), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Checkbox( + // Чекбокс для капитанов + value: capitan, + checkColor: Colors.blue, + activeColor: Colors.white, + onChanged: (value) { + setState( + () { + capitan = value!; + }, + ); + }, + ), + Text( + 'Я капитан команды', + style: TextStyle( + color: Colors.white, + ), + ), + ], + ), + Container( + child: capitan + ? Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Введите название вашей команды', + style: TextStyle( + color: Colors.white, + ), + ), + ), + TextField( + // Ввод названия команды для капитана + decoration: InputDecoration( + fillColor: Colors.white, filled: true), + controller: teamController, + onChanged: (name) { + setState(() {}); + }, + textAlign: TextAlign.center, + ), + ], + ) + : false // Проверка существуют ли команды, чтобы в них зарегистрироваться + ? Column( + // Для пустого списка + children: [ + Text( + 'Ни одной доступной команды нет', + style: TextStyle( + color: Colors.white, + ), + ), + Text( + 'Можешь создать команду сам \u261d', + style: TextStyle( + color: Colors.white, + ), + ) + ], + ) + : Column( + // Для непустого списка + children: [ + Observer( + builder: (_) => Text( + login!.userName, + //'Выбери свою команду', + style: TextStyle( + color: Colors.white, + ), + ), + ), + // DropdownButton( + // value: teamSelect, + // onChanged: (newName) { + // setState(() { + // teamSelect = newName; + // }); + // }, + // items: [ + // ...context + // .watch() + // .allTeamNames + // .map>( + // (String team) => DropdownMenuItem( + // child: Text(team), + // value: team, + // ), + // ) + // .toList(), + // ], + // ), + ], + ), + ), + ], + ), + ), + // ElevatedButton( + // // Кнопка регистрации + // style: ButtonStyle( + // backgroundColor: MaterialStateProperty.all(Colors.green), + // ), + // onPressed: context + // .watch() + // .signIn && // Проверка входа в Google-аккаунт + // ((capitan && // Проверка для капитана + // teamController.text + // .trim() + // .isNotEmpty) || // Проверка пустое ли название команды + // (!capitan && // Проверки для некапитанов + // context + // .watch() + // .allTeamNames + // .isNotEmpty && // или список команд должен быть не пустым + // teamSelect != null)) // и команда должна быть выбрана + // ? () async { + // if (capitan && + // !(await DatabaseService().checkTeamName( + // // Проверка уникальности имени команды + // name: teamController.text.trim()))) { + // Fluttertoast.showToast( + // msg: 'Команда с таким названием уже зарегистрирована', + // toastLength: Toast.LENGTH_LONG, + // ); + // } else { + // context + // .read() + // .registrationPlayer( + // // Регистрация игрока + // uid: context.read().userId, + // capitan: capitan, + // name: widget.name, + // team: + // capitan ? teamController.text.trim() : teamSelect, + // ) + // .then((value) => context.read().registedUser()) + // .then((value) { + // if (capitan) // Если капитан, то необходимо зарегистрировать команду + // context // Регистрация команды + // .read() + // .registrationTeam( + // title: teamController.text.trim()); + // context + // .read() + // .initMeAndMyTeam(uid: context.read().userId); + // }); + // } + // } // Функция регистрации + // : null, + // child: Text(capitan ? 'Зарегистрировать команду' : widget.message), + // ), + ElevatedButton( + onPressed: () { + Fluttertoast.showToast(msg: 'Name is ' + widget.name); + }, + child: Text('Show name'), + ), + ], + ); + } +} diff --git a/team_c_f/lib/data/singledata/login.dart b/team_c_f/lib/data/singledata/login.dart new file mode 100644 index 0000000..8dd863a --- /dev/null +++ b/team_c_f/lib/data/singledata/login.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/store/login/login.dart'; + +class DataLogin extends ChangeNotifier{ + Login? login; + + DataLogin() + { + login = Login(); + } +} \ No newline at end of file diff --git a/team_c_f/lib/element/player.dart b/team_c_f/lib/element/player.dart deleted file mode 100644 index 1f53206..0000000 --- a/team_c_f/lib/element/player.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/servise/make.dart'; -import 'package:adaptive_dialog/adaptive_dialog.dart'; -import 'package:provider/provider.dart'; -import 'package:team_c_f/data/tournament.dart'; - -class ShowPlayer extends StatelessWidget { - // Класс отображающий информацию об указанном игроке - final Player player; - ShowPlayer({Key key, @required this.player}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - child: InkWell( - onLongPress: () async { - if (context.read().me.capitan) if (await showAlertDialog( - context: context, - title: 'Изменение состава', - message: 'Удалить ${player.name}', - actions: [ - AlertDialogAction( - key: true, - label: 'Да, удалить', - isDefaultAction: true, - ), - AlertDialogAction( - key: false, - label: 'Отмена', - isDestructiveAction: true, - ), - ], - )) context.read().removePlayerFromMyTeam(uid: player.uid); - }, - child: Card( - child: ListTile( - leading: CircleAvatar( - child: Text(player.position.toString()), - ), - title: Text(player.name), - trailing: Text(showPoints(player.points)), - ), - ), - ), - ); - } -} diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart index b5d443e..7a48fb2 100644 --- a/team_c_f/lib/main.dart +++ b/team_c_f/lib/main.dart @@ -1,13 +1,9 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/shortmatch.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/page/home.dart'; -import 'package:team_c_f/page/sign.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:onesignal_flutter/onesignal_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/components/login.dart'; +import 'package:team_c_f/data/singledata/login.dart'; Future main() async { myApp(); @@ -17,8 +13,6 @@ myApp() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // Инициализация Firebase - //OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none); - OneSignal.shared.init('93b27d54-e442-4af5-86e4-a215faf20e3a', iOSSettings: { OSiOSSettings.autoPrompt: false, OSiOSSettings.inAppLaunchUrl: false @@ -26,298 +20,21 @@ myApp() async { OneSignal.shared .setInFocusDisplayType(OSNotificationDisplayType.notification); - runApp( - MultiProvider( - // Мультипровайдер, для упроощения взаимодействия с данными - providers: [ - ChangeNotifierProvider( - create: (context) => Account(), - ), // Данные связанные с аутентификацией (гугл-вход и регистрация в приложении) - ChangeNotifierProvider( - create: (context) => Tournament(), - ), // Данные полученные из Firebase - ChangeNotifierProvider( - create: (context) => DataMatch(), - ), - ], - child: MaterialApp( - // theme: ThemeData( - // textTheme: TextTheme( - // bodyText2: TextStyle( - // color: Colors.black, - // fontWeight: FontWeight.normal, - // ), - // bodyText1: TextStyle( - // color: Colors.black, - // decoration: TextDecoration.lineThrough, - // fontWeight: FontWeight.normal, - // ), - // caption: TextStyle( - // color: Colors.green, - // fontWeight: FontWeight.w400, - // ), - // ), - // ), - home: SafeArea( - child: Page(), - ), - ), - ), - ); -} - -class Page extends StatefulWidget { - const Page({Key key}) : super(key: key); - - @override - _PageState createState() => _PageState(); + runApp(LoginPage()); } -class _PageState extends State { +class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - child: context - .watch() - .registedInApp // Проверка зарегистрирован ли пользователь в приложении - ? Homepage() // Домашняя страница приложения - : Sign(), // Регистрация в приложении + вход в гугл + return MaterialApp( + home: ChangeNotifierProvider( + create: (_) => DataLogin(), + child: SafeArea( + child: Scaffold( + body: LoginView(), + ), + ), + ), ); } -} - -// class Prob extends StatelessWidget { -// const Prob({Key key}) : super(key: key); - -// @override -// Widget build(BuildContext context) { -// return Container( -// child: Text( -// '1 - 1', -// style: Theme.of(context).textTheme.bodyText2, -// ), -// ); -// } -// } - -// class Content extends StatefulWidget { -// const Content({Key key}) : super(key: key); - -// @override -// _ContentState createState() => _ContentState(); -// } - -// class _ContentState extends State { -// Tournament tournament; -// String currentTour = 'start msg'; -// int matchNumber = 0; -// Team home; -// Team away; -// bool dataDownload = false; - -// Tournament parseTournament(String responseBody) { -// final parsed = json.decode(responseBody); - -// return Tournament.fromJson(parsed); -// } - -// Future downloadInfo(http.Client client) async { -// final response = await client -// .get(Uri.parse('http://tcfserver.azurewebsites.net/info?tour=31')); - -// return parseTournament(response.body); -// } - -// changeMatch(int index, CarouselPageChangedReason reason) { -// setState(() { -// matchNumber = index; -// home = tournament.teams -// .where((element) => element.name == tournament.pair[matchNumber * 2]) -// .first; -// away = tournament.teams -// .where( -// (element) => element.name == tournament.pair[matchNumber * 2 + 1]) -// .first; -// }); -// } - -// void download() async { -// downloadInfo(http.Client()).then( -// (all) => setState(() { -// currentTour = 'Текущий тур ${all.currentTour}'; -// tournament = all; -// home = all.teams -// .where((element) => element.name == all.pair[matchNumber * 2]) -// .first; -// away = all.teams -// .where((element) => element.name == all.pair[matchNumber * 2 + 1]) -// .first; -// dataDownload = true; -// }), -// ); -// setState(() { -// currentTour = 'Загрузка данных'; -// }); -// } - -// Widget headerBuilder(int i) { -// Team home = tournament.teams -// .where((element) => element.name == tournament.pair[i * 2]) -// .first; -// Team away = tournament.teams -// .where((element) => element.name == tournament.pair[i * 2 + 1]) -// .first; -// return Container( -// decoration: BoxDecoration( -// borderRadius: BorderRadius.circular(20), -// color: Colors.blue[100], -// ), -// alignment: Alignment.center, -// margin: const EdgeInsets.symmetric( -// vertical: 8, -// ), -// child: Column( -// mainAxisSize: MainAxisSize.max, -// mainAxisAlignment: MainAxisAlignment.center, -// children: [ -// Row( -// mainAxisSize: MainAxisSize.max, -// children: [ -// Expanded( -// flex: 2, -// child: Text( -// '${home.countPerRound}', -// textAlign: TextAlign.center, -// style: TextStyle( -// fontSize: 30, -// ), -// ), -// ), -// Expanded( -// flex: 1, -// child: Text( -// '-', -// textAlign: TextAlign.center, -// style: TextStyle( -// fontSize: 30, -// ), -// ), -// ), -// Expanded( -// flex: 2, -// child: Text( -// '${away.countPerRound}', -// textAlign: TextAlign.center, -// style: TextStyle( -// fontSize: 30, -// ), -// ), -// ), -// ], -// ), -// Expanded( -// flex: 1, -// child: Row( -// children: [ -// Expanded( -// flex: 1, -// child: Text( -// '${home.name.split("\"")[1]}', -// textAlign: TextAlign.center, -// style: TextStyle( -// fontSize: 18, -// ), -// ), -// ), -// SizedBox( -// width: 20, -// ), -// Expanded( -// flex: 1, -// child: Text( -// '${away.name.split("\"")[1]}', -// textAlign: TextAlign.center, -// style: TextStyle( -// fontSize: 18, -// ), -// ), -// ), -// ], -// ), -// ), -// ], -// ), -// ); -// } - -// @override -// Widget build(BuildContext context) { -// Widget wrap() { -// return Column( -// children: [ -// Wrap( -// spacing: 10, -// runSpacing: 10, -// alignment: WrapAlignment.center, -// direction: Axis.horizontal, -// children: [ -// for (int i = 0; i < 10; i++) -// Meet( -// number: i, -// home: home, -// away: away, -// real: tournament.realResults, -// rHome: tournament.names.team[i * 2], -// rAway: tournament.names.team[i * 2 + 1], -// info: tournament.names.info[i], -// ) -// ], -// ), -// ], -// ); -// } - -// Widget headers() { -// return CarouselSlider( -// items: [ -// for (int i = 0; i * 2 < tournament.pair.length; i++) headerBuilder(i) -// ], -// options: CarouselOptions( -// autoPlay: false, -// enlargeCenterPage: true, -// onPageChanged: changeMatch, -// aspectRatio: 4, -// ), -// ); -// } - -// return Container( -// color: Colors.indigo, -// alignment: Alignment.center, -// width: double.infinity, -// height: double.infinity, -// padding: const EdgeInsets.all(10), -// child: Column( -// children: [ -// dataDownload ? headers() : SizedBox(height: 0), -// Expanded( -// child: Container( -// child: ListView( -// children: [ -// dataDownload ? wrap() : Text('Прогнозы ещё не загружены'), -// ElevatedButton( -// child: Text('Download'), -// onPressed: download, -// ), -// Text( -// currentTour, -// ), -// ], -// ), -// ), -// ), -// ], -// ), -// ); -// } -// } +} \ No newline at end of file diff --git a/team_c_f/lib/data/currenttour.dart b/team_c_f/lib/old/data/currenttour.dart similarity index 58% rename from team_c_f/lib/data/currenttour.dart rename to team_c_f/lib/old/data/currenttour.dart index 3a01d59..f4801cd 100644 --- a/team_c_f/lib/data/currenttour.dart +++ b/team_c_f/lib/old/data/currenttour.dart @@ -1,17 +1,17 @@ import 'package:flutter/material.dart'; class CurrentTour { // Класс с данными о текущем туре - final String tour; // Номер или стадия текущего тура - final String tournament; // Название текущей стадии + final String? tour; // Номер или стадия текущего тура + final String? tournament; // Название текущей стадии CurrentTour({ // Базовый конструктор @required this.tour, @required this.tournament, }); - factory CurrentTour.fromJson({Map json}) { // Именованный конструктор, используется для десериализации + factory CurrentTour.fromJson({Map? json}) { // Именованный конструктор, используется для десериализации return CurrentTour( - tour: json['Tour'], + tour: json!['Tour'], tournament: json['Tournament'], ); } diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/old/data/data.dart similarity index 59% rename from team_c_f/lib/data/data.dart rename to team_c_f/lib/old/data/data.dart index a95623b..1110e25 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/old/data/data.dart @@ -1,18 +1,18 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; -import 'package:team_c_f/servise/auth.dart'; -import 'package:team_c_f/servise/operationdb.dart'; +import 'package:team_c_f/old/servise/auth.dart'; +import 'package:team_c_f/old/servise/operationdb.dart'; class Account with ChangeNotifier { // Единый класс с информацией о Google-аккаунте и регистрации в приложении - bool _signInGoogle = false; - bool _registedInApp = false; - String _userId = ''; + bool? _signInGoogle = false; + bool? _registedInApp = false; + String? _userId = ''; - bool get signIn => _signInGoogle; // Выполнен вход в Google-аккаунт + bool get signIn => _signInGoogle!; // Выполнен вход в Google-аккаунт bool get registedInApp => - _registedInApp; // Выполнена ли регистрации в приложении - String get userId => _userId; // Уникальный идентификатор Google-аккаунта + _registedInApp!; // Выполнена ли регистрации в приложении + String get userId => _userId!; // Уникальный идентификатор Google-аккаунта Account() { // Конструктор @@ -22,9 +22,9 @@ class Account with ChangeNotifier { void calculateVariables() { // Вычисление переменных if (FirebaseAuth.instance.currentUser != null) { - _userId = FirebaseAuth.instance.currentUser.uid; + _userId = FirebaseAuth.instance.currentUser!.uid; _signInGoogle = true; - DatabaseService().userExists(userId: _userId).then((value) { + DatabaseService().userExists(userId: _userId!).then((value) { _registedInApp = value; notifyListeners(); }); @@ -38,7 +38,7 @@ class Account with ChangeNotifier { Future changeSignIn() async { // Изменение статуса входа в Google-аккаунт - _signInGoogle ? await signOutGoogle() : await signInWithGoogle(); + _signInGoogle! ? await signOutGoogle() : await signInWithGoogle(); calculateVariables(); } diff --git a/team_c_f/lib/data/forecast.dart b/team_c_f/lib/old/data/forecast.dart similarity index 75% rename from team_c_f/lib/data/forecast.dart rename to team_c_f/lib/old/data/forecast.dart index 40d9e6f..1d0c3fb 100644 --- a/team_c_f/lib/data/forecast.dart +++ b/team_c_f/lib/old/data/forecast.dart @@ -1,24 +1,23 @@ import 'dart:convert'; -import 'package:flutter/material.dart'; -import 'package:team_c_f/data/match.dart'; -import 'package:team_c_f/servise/make.dart'; +import 'package:team_c_f/old/data/match.dart'; +import 'package:team_c_f/old/servise/make.dart'; class Forecast { // Информация о прогнозе - String _docId; // Идентификатор документа с прогнозом + late String _docId; // Идентификатор документа с прогнозом final String userId; // Идентификатор Google-аккаунта участника оставившего прогноз final String tour; // Номер тура final List rate; // Список прогнозов - int _points; // Количество набранных очков + late int _points; // Количество набранных очков final String team; Forecast({ // Конструктор - @required this.userId, - @required this.tour, - @required this.rate, - @required this.team, + required this.userId, + required this.tour, + required this.rate, + required this.team, }); set docId(String docId) { @@ -27,7 +26,7 @@ class Forecast { int get points => _points; - factory Forecast.fromJson({Map json, String docId}) { + factory Forecast.fromJson({required Map json, required String docId}) { // Именованный конструктор для десериализации Forecast f = Forecast( userId: json['UserId'], diff --git a/team_c_f/lib/data/match.dart b/team_c_f/lib/old/data/match.dart similarity index 78% rename from team_c_f/lib/data/match.dart rename to team_c_f/lib/old/data/match.dart index d506bac..cee18d0 100644 --- a/team_c_f/lib/data/match.dart +++ b/team_c_f/lib/old/data/match.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - class Match { // Информация о матче final String home; // Хозяева @@ -11,15 +9,15 @@ class Match { Match({ // Базовый конструктов - @required this.home, - @required this.away, - @required this.time, - @required this.date, - @required this.score, - @required this.started, + required this.home, + required this.away, + required this.time, + required this.date, + required this.score, + required this.started, }); - factory Match.fromJson({Map json}) { + factory Match.fromJson({required Map json}) { // Именованный конструктор, используемый при десериализации return Match( home: json['Home'], diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/old/data/player.dart similarity index 74% rename from team_c_f/lib/data/player.dart rename to team_c_f/lib/old/data/player.dart index fbb3d29..ef885e9 100644 --- a/team_c_f/lib/data/player.dart +++ b/team_c_f/lib/old/data/player.dart @@ -1,10 +1,8 @@ -import 'package:flutter/material.dart'; - class Player { // Информация об участнике - String docId; // Идентификатор документа с информацией об участнике + late String docId; // Идентификатор документа с информацией об участнике final String name; // Имя и фамилия участника - String uid; // Идентификатор Google-аккаунта участника + late String uid; // Идентификатор Google-аккаунта участника bool capitan; // Флаг капитана bool confirmed; // Флаг подтверждения участия в команде String team; // Название команды @@ -13,18 +11,18 @@ class Player { Player({ // Конструктор - @required this.name, - @required String uid, - @required this.capitan, - @required this.team, - @required this.confirmed, + required this.name, + required String uid, + required this.capitan, + required this.team, + required this.confirmed, this.points = 0, this.position = 1, }) { this.uid = uid; } - factory Player.fromJson({Map json, String docId}) { + factory Player.fromJson({required Map json, required String docId}) { // Именованный конструктор для десериализации Player p = Player( name: json['Name'], diff --git a/team_c_f/lib/data/push.dart b/team_c_f/lib/old/data/push.dart similarity index 75% rename from team_c_f/lib/data/push.dart rename to team_c_f/lib/old/data/push.dart index 5bec592..fa2dd15 100644 --- a/team_c_f/lib/data/push.dart +++ b/team_c_f/lib/old/data/push.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; class Push { @@ -6,19 +5,19 @@ class Push { final String ruTitle; final String enContent; final String ruContent; - final DateTime date; + final DateTime? date; Push({ - @required this.enTitle, - @required this.ruTitle, - @required this.enContent, - @required this.ruContent, + required this.enTitle, + required this.ruTitle, + required this.enContent, + required this.ruContent, this.date, }); String toJson() { String lateSend = (date != null) - ? '"send_after": "${DateFormat('yyyy-MM-dd HH:mm:ss').format(date)}",' + ? '"send_after": "${DateFormat('yyyy-MM-dd HH:mm:ss').format(date!)}",' : ''; return '{"app_id": "93b27d54-e442-4af5-86e4-a215faf20e3a",' + '"headings" : {"en": "$enTitle", "ru": "$ruTitle"},' + diff --git a/team_c_f/lib/data/schedule.dart b/team_c_f/lib/old/data/schedule.dart similarity index 80% rename from team_c_f/lib/data/schedule.dart rename to team_c_f/lib/old/data/schedule.dart index 71df023..ccf09fd 100644 --- a/team_c_f/lib/data/schedule.dart +++ b/team_c_f/lib/old/data/schedule.dart @@ -1,11 +1,10 @@ import 'dart:convert'; -import 'package:team_c_f/data/match.dart'; -import 'package:flutter/material.dart'; +import 'package:team_c_f/old/data/match.dart'; import 'package:intl/intl.dart'; class Tour { // Информация о туре - String docId; // Идентификатор документа с информацией о туре + late String docId; // Идентификатор документа с информацией о туре final String tour; // Номер тура final List pair; // Список участников тура List matches = []; // Список матчей тура @@ -16,22 +15,22 @@ class Tour { Tour.basic({ // Именованный конструктор, используемый администраторами для создания расписания - @required this.tour, - @required this.pair, + required this.tour, + required this.pair, }); Tour({ // Конструктор - @required this.tour, - @required this.pair, - @required this.matches, - @required this.deadline, - @required this.ending, + required this.tour, + required this.pair, + required this.matches, + required this.deadline, + required this.ending, }); bool get show => _show; - factory Tour.fromJson({Map json, String docId}) { + factory Tour.fromJson({required Map json, required String docId}) { // Именованный конструктор, используемый для десериализации Tour t = Tour( tour: json['Tour'], diff --git a/team_c_f/lib/data/shortmatch.dart b/team_c_f/lib/old/data/shortmatch.dart similarity index 81% rename from team_c_f/lib/data/shortmatch.dart rename to team_c_f/lib/old/data/shortmatch.dart index 43e9ce0..f984565 100644 --- a/team_c_f/lib/data/shortmatch.dart +++ b/team_c_f/lib/old/data/shortmatch.dart @@ -1,16 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/match.dart'; +import 'package:team_c_f/old/data/match.dart'; class ShortMatch extends Match { // Основаная информация о матче, используется при выборе матчей String tournament; bool selected = false; ShortMatch({ - String home, - String away, - String time, - String date, - @required this.tournament, + required String home, + required String away, + required String time, + required String date, + required this.tournament, }) : super( home: home, away: away, diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/old/data/team.dart similarity index 79% rename from team_c_f/lib/data/team.dart rename to team_c_f/lib/old/data/team.dart index 6259ae1..b5b9b7f 100644 --- a/team_c_f/lib/data/team.dart +++ b/team_c_f/lib/old/data/team.dart @@ -1,10 +1,8 @@ import 'dart:convert'; -import 'package:flutter/material.dart'; - class Team { // Информация о команде - String docId; // Идентификатор документа с командой на сервере + late String docId; // Идентификатор документа с командой на сервере final String title; // Название команды final List members; // Список участников int points = 0; // Количество очков в чемпионате @@ -12,13 +10,13 @@ class Team { Team({ // Конструктор - @required this.title, - @required this.members, + required this.title, + required this.members, this.points = 0, this.position = 1, }); - factory Team.fromJson({Map json, String docId}) { + factory Team.fromJson({required Map json, required String docId}) { // Именованный конструктор, используемый при десериализации Team t = Team( title: json['Title'], diff --git a/team_c_f/lib/data/tournament.dart b/team_c_f/lib/old/data/tournament.dart similarity index 85% rename from team_c_f/lib/data/tournament.dart rename to team_c_f/lib/old/data/tournament.dart index f7b5937..54a0d4b 100644 --- a/team_c_f/lib/data/tournament.dart +++ b/team_c_f/lib/old/data/tournament.dart @@ -1,26 +1,26 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:team_c_f/data/currenttour.dart'; -import 'package:team_c_f/data/forecast.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/push.dart'; -import 'package:team_c_f/data/schedule.dart'; -import 'package:team_c_f/data/shortmatch.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/servise/operationdb.dart'; +import 'package:team_c_f/old/data/currenttour.dart'; +import 'package:team_c_f/old/data/forecast.dart'; +import 'package:team_c_f/old/data/player.dart'; +import 'package:team_c_f/old/data/push.dart'; +import 'package:team_c_f/old/data/schedule.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; +import 'package:team_c_f/old/data/team.dart'; +import 'package:team_c_f/old/servise/operationdb.dart'; import 'package:intl/intl.dart'; import 'package:http/http.dart' as http; class Tournament with ChangeNotifier { // Класс хранящий актуальную информацию с сервера - List allTeams = []; // Все команды - CurrentTour current; // Информацию о текущем туре - List schedule = []; // Расписание - List currentForecasts = []; // Прогнозы на текущий тур - List allPlayers = []; // Все игроки - Player me; // Текущий игрок - Team myTeam; // Моя команда - String selectTour = ''; // Тур для просмотра + late List allTeams = []; // Все команды + late CurrentTour current; // Информацию о текущем туре + late List schedule = []; // Расписание + late List currentForecasts = []; // Прогнозы на текущий тур + late List allPlayers = []; // Все игроки + late Player me; // Текущий игрок + late Team? myTeam; // Моя команда + late String selectTour = ''; // Тур для просмотра // bool leaveForecastForSelectedTour = // false; // Оставлен ли прогноз на текущий тур @@ -32,7 +32,7 @@ class Tournament with ChangeNotifier { current = currentTour; Stream> streamCurrentForecast = - DatabaseService().getCurrentForecasts(stage: current.tour); + DatabaseService().getCurrentForecasts(stage: current.tour!); streamCurrentForecast.listen( (List forecasts) { currentForecasts = forecasts; @@ -85,7 +85,7 @@ class Tournament with ChangeNotifier { ); } - Future checkForecast({@required String stage}) async { + Future checkForecast({required String stage}) async { return DatabaseService().checkForecast(uid: me.uid, stage: stage); } @@ -99,7 +99,7 @@ class Tournament with ChangeNotifier { : []; } - void initMeAndMyTeam({@required String uid}) { + void initMeAndMyTeam({required String uid}) { // Инициализация для более быстрой работы if (allPlayers.isNotEmpty) me = allPlayers.where((player) => player.uid == uid).single; @@ -146,7 +146,7 @@ class Tournament with ChangeNotifier { notifyListeners(); } - void confirmPlayer({@required String uid, @required bool confirm}) { + void confirmPlayer({required String uid, required bool confirm}) { // Подтверждение игрока и доабвление его в команду Player p = allPlayers.where((player) => player.uid == uid).single; Team t = allTeams.where((team) => team.title == p.team).single; @@ -156,7 +156,7 @@ class Tournament with ChangeNotifier { DatabaseService().updatePlayer(player: p); } - void removePlayerFromMyTeam({@required String uid}) { + void removePlayerFromMyTeam({required String uid}) { // Удаление игрока из команды и обнуление команды у игрока Player p = allPlayers.where((player) => player.uid == uid).first; Team t = allTeams.where((team) => team.title == p.team).first; @@ -167,7 +167,7 @@ class Tournament with ChangeNotifier { DatabaseService().updatePlayer(player: p); } - void createSchedule({@required List tours}) { + void createSchedule({required List tours}) { //Создание расписания tours.forEach( (tour) { @@ -185,7 +185,7 @@ class Tournament with ChangeNotifier { notifyListeners(); } - Future getTour({@required String tour}) async { + Future getTour({required String tour}) async { // Получение информации о туре Tour t = await DatabaseService().getTour(stage: tour).first; schedule.setAll( @@ -193,19 +193,19 @@ class Tournament with ChangeNotifier { return t; } - Future makeForecast({@required Forecast forecast}) { + Future makeForecast({required Forecast forecast}) { return DatabaseService().makeForecast(forecast: forecast).then( (response) => DatabaseService() .checkForecast(uid: me.uid, stage: forecast.tour), ); } - Future getCurrentForecast({@required String stage}) { + Future getCurrentForecast({required String stage}) { return DatabaseService().getForecast(uid: me.uid, tour: stage); } void createMatchesForTour( - {@required List matches, String stage}) { + {required List matches, String? stage}) { // Добавление матчей для прогнозирования на сервер Tour t = schedule.where((tour) => tour.tour == stage).single; matches.sort( @@ -232,7 +232,7 @@ class Tournament with ChangeNotifier { String notifyNow = Push( enTitle: 'New tour', enContent: - 'You can leave a forecast for ${!stage.contains(' ') ? '$stage round' : stage}', + 'You can leave a forecast for ${!stage!.contains(' ') ? '$stage round' : stage}', ruTitle: 'Новый тур', ruContent: 'Можно оставить прогноз на ${!stage.contains(' ') ? '$stage тур' : '$stage'}', diff --git a/team_c_f/lib/element/createschedule.dart b/team_c_f/lib/old/element/createschedule.dart similarity index 95% rename from team_c_f/lib/element/createschedule.dart rename to team_c_f/lib/old/element/createschedule.dart index 1e82b56..7a8ff20 100644 --- a/team_c_f/lib/element/createschedule.dart +++ b/team_c_f/lib/old/element/createschedule.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/schedule.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/servise/make.dart'; +import 'package:team_c_f/old/data/schedule.dart'; +import 'package:team_c_f/old/data/tournament.dart'; +import 'package:team_c_f/old/servise/make.dart'; class CreateSchedule extends StatefulWidget { // Класс отображающий виджет для создания основы расписания - const CreateSchedule({Key key}) : super(key: key); + const CreateSchedule({Key? key}) : super(key: key); @override _CreateScheduleState createState() => _CreateScheduleState(); diff --git a/team_c_f/lib/element/forecast.dart b/team_c_f/lib/old/element/forecast.dart similarity index 94% rename from team_c_f/lib/element/forecast.dart rename to team_c_f/lib/old/element/forecast.dart index 75e2bd8..170fa8d 100644 --- a/team_c_f/lib/element/forecast.dart +++ b/team_c_f/lib/old/element/forecast.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/match.dart'; -import 'package:team_c_f/page/leaveforecast.dart'; +import 'package:team_c_f/old/data/match.dart'; +import 'package:team_c_f/old/page/leaveforecast.dart'; class ForecastView extends StatefulWidget { final int index; final Match match; ForecastView({ - Key key, - @required this.match, - @required this.index, + Key? key, + required this.match, + required this.index, }) : super(key: key); @override @@ -16,8 +16,8 @@ class ForecastView extends StatefulWidget { } class _ForecastViewState extends State { - String home; - String away; + String? home; + String? away; List numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; int get index => widget.index; @@ -62,7 +62,7 @@ class _ForecastViewState extends State { setState( () { home = result; - LeaveForecast.rate[index] = home + + LeaveForecast.rate[index] = home! + '-' + LeaveForecast.rate[index].split('-')[1]; }, @@ -95,7 +95,7 @@ class _ForecastViewState extends State { LeaveForecast.rate[index] = LeaveForecast.rate[index].split('-')[0] + '-' + - away; + away!; }, ); }, diff --git a/team_c_f/lib/element/match.dart b/team_c_f/lib/old/element/match.dart similarity index 95% rename from team_c_f/lib/element/match.dart rename to team_c_f/lib/old/element/match.dart index 7f46934..8a04f90 100644 --- a/team_c_f/lib/element/match.dart +++ b/team_c_f/lib/old/element/match.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/match.dart'; +import 'package:team_c_f/old/data/match.dart'; import 'package:intl/intl.dart'; class MatchView extends StatelessWidget { // Показ одного выбранного матча для прогнозирования final Match match; - const MatchView({Key key, this.match}) : super(key: key); + const MatchView({Key? key, required this.match}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/element/meet.dart b/team_c_f/lib/old/element/meet.dart similarity index 86% rename from team_c_f/lib/element/meet.dart rename to team_c_f/lib/old/element/meet.dart index 182a82b..3a429fa 100644 --- a/team_c_f/lib/element/meet.dart +++ b/team_c_f/lib/old/element/meet.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; class MeetView extends StatelessWidget { // Показ одного выбранного матча для прогнозирования final String match; - const MeetView({Key key, this.match}) : super(key: key); + const MeetView({Key? key, required this.match}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/element/notconfirmedplayer.dart b/team_c_f/lib/old/element/notconfirmedplayer.dart similarity index 91% rename from team_c_f/lib/element/notconfirmedplayer.dart rename to team_c_f/lib/old/element/notconfirmedplayer.dart index 36b1d10..958e80a 100644 --- a/team_c_f/lib/element/notconfirmedplayer.dart +++ b/team_c_f/lib/old/element/notconfirmedplayer.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/tournament.dart'; +import 'package:team_c_f/old/data/player.dart'; +import 'package:team_c_f/old/data/tournament.dart'; import 'package:provider/provider.dart'; class PlayerToConfirm extends StatelessWidget { // Класс, для отображения неподтвержденных игроков final Player player; // Неподтвержденный игрок - PlayerToConfirm({Key key, @required this.player}) : super(key: key); + PlayerToConfirm({Key? key, required this.player}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/old/element/player.dart b/team_c_f/lib/old/element/player.dart new file mode 100644 index 0000000..0d491f9 --- /dev/null +++ b/team_c_f/lib/old/element/player.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/old/data/player.dart'; +import 'package:team_c_f/old/servise/make.dart'; +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/old/data/tournament.dart'; + +class ShowPlayer extends StatelessWidget { + // Класс отображающий информацию об указанном игроке + final Player player; + ShowPlayer({Key? key, required this.player}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: InkWell( + onLongPress: () async { + if (context.read().me.capitan && + (await showAlertDialog( + context: context, + title: 'Изменение состава', + message: 'Удалить ${player.name}', + actions: [ + AlertDialogAction( + key: true, + label: 'Да, удалить', + isDefaultAction: true, + ), + AlertDialogAction( + key: false, + label: 'Отмена', + isDestructiveAction: true, + ), + ], + ))!) { + context.read().removePlayerFromMyTeam(uid: player.uid); + } + }, + child: Card( + child: ListTile( + leading: CircleAvatar( + child: Text(player.position.toString()), + ), + title: Text(player.name), + trailing: Text(showPoints(player.points)), + ), + ), + ), + ); + } +} diff --git a/team_c_f/lib/element/schedule.dart b/team_c_f/lib/old/element/schedule.dart similarity index 87% rename from team_c_f/lib/element/schedule.dart rename to team_c_f/lib/old/element/schedule.dart index e3e3218..d26d3b6 100644 --- a/team_c_f/lib/element/schedule.dart +++ b/team_c_f/lib/old/element/schedule.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/schedule.dart'; +import 'package:team_c_f/old/data/schedule.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/tournament.dart'; +import 'package:team_c_f/old/data/tournament.dart'; class TourView extends StatelessWidget { // Элементы, отвечающие за вид туров при их выборе final Tour tour; - const TourView({Key key, @required this.tour}) : super(key: key); + const TourView({Key? key, required this.tour}) : super(key: key); @override Widget build(BuildContext context) { @@ -19,7 +19,7 @@ class TourView extends StatelessWidget { // Элементы, отвечающи : tour.tour.length != 12 ? tour.tour.substring(4) : tour.tour.substring(6); - TextStyle styleTitle = tour.tour.length != 12 + TextStyle? styleTitle = tour.tour.length != 12 ? Theme.of(context).textTheme.headline5 : Theme.of(context).textTheme.headline6; return Container( diff --git a/team_c_f/lib/element/selectTeam.dart b/team_c_f/lib/old/element/selectTeam.dart similarity index 96% rename from team_c_f/lib/element/selectTeam.dart rename to team_c_f/lib/old/element/selectTeam.dart index 498dca2..2a62f78 100644 --- a/team_c_f/lib/element/selectTeam.dart +++ b/team_c_f/lib/old/element/selectTeam.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/tournament.dart'; +import 'package:team_c_f/old/data/data.dart'; +import 'package:team_c_f/old/data/tournament.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/servise/operationdb.dart'; +import 'package:team_c_f/old/servise/operationdb.dart'; class SelectTeam extends StatefulWidget { // Класс отображения выбора команды или регистрации новой final String message; - final String name; - SelectTeam({Key key, @required this.message, this.name}) : super(key: key); + final String? name; + SelectTeam({Key? key, required this.message, this.name}) : super(key: key); @override _SelectTeamState createState() => _SelectTeamState(); @@ -17,7 +17,7 @@ class SelectTeam extends StatefulWidget { class _SelectTeamState extends State { TextEditingController teamController = TextEditingController(); - String teamSelect; + String? teamSelect; bool capitan = false; @override Widget build(BuildContext context) { @@ -43,7 +43,7 @@ class _SelectTeamState extends State { onChanged: (value) { setState( () { - capitan = value; + capitan = value!; }, ); }, diff --git a/team_c_f/lib/element/team.dart b/team_c_f/lib/old/element/team.dart similarity index 84% rename from team_c_f/lib/element/team.dart rename to team_c_f/lib/old/element/team.dart index 8006eab..27d8305 100644 --- a/team_c_f/lib/element/team.dart +++ b/team_c_f/lib/old/element/team.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/element/player.dart'; +import 'package:team_c_f/old/data/team.dart'; +import 'package:team_c_f/old/data/tournament.dart'; +import 'package:team_c_f/old/element/player.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/servise/make.dart'; +import 'package:team_c_f/old/servise/make.dart'; class ShowTeam extends StatelessWidget { // Класс отображения информации об указанной команде final Team team; // Команда - ShowTeam({Key key, @required this.team}) : super(key: key); + ShowTeam({Key? key, required this.team}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/element/tour.dart b/team_c_f/lib/old/element/tour.dart similarity index 79% rename from team_c_f/lib/element/tour.dart rename to team_c_f/lib/old/element/tour.dart index 974236d..a47a06f 100644 --- a/team_c_f/lib/element/tour.dart +++ b/team_c_f/lib/old/element/tour.dart @@ -1,25 +1,25 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/forecast.dart'; -import 'package:team_c_f/data/schedule.dart'; -import 'package:team_c_f/data/shortmatch.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/element/meet.dart'; -import 'package:team_c_f/element/match.dart'; -import 'package:team_c_f/page/leaveforecast.dart'; -import 'package:team_c_f/page/selectmatch.dart'; +import 'package:team_c_f/old/data/forecast.dart'; +import 'package:team_c_f/old/data/schedule.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; +import 'package:team_c_f/old/data/tournament.dart'; +import 'package:team_c_f/old/element/meet.dart'; +import 'package:team_c_f/old/element/match.dart'; +import 'package:team_c_f/old/page/leaveforecast.dart'; +import 'package:team_c_f/old/page/selectmatch.dart'; class ShowTour extends StatefulWidget { // Класс, отображающий результаты выбранного тура тура - final String tour; - ShowTour({Key key, this.tour}) : super(key: key); + final String? tour; + ShowTour({Key? key, this.tour}) : super(key: key); @override _ShowTourState createState() => _ShowTourState(); } class _ShowTourState extends State { - Tour selectTour; + Tour? selectTour; bool leaveForecast = false; @override @@ -28,11 +28,9 @@ class _ShowTourState extends State { context .read() .getTour( - tour: widget.tour == null - ? context.read().selectTour == null - ? '1' - : context.read().selectTour - : widget.tour) + tour: (widget.tour == null + ? context.read().selectTour + : widget.tour)!) .then( (value) { setState( @@ -40,12 +38,12 @@ class _ShowTourState extends State { selectTour = value; }, ); - context.read().checkForecast(stage: selectTour.tour).then( - (response) { + context.read().checkForecast(stage: selectTour!.tour).then( + (bool response) async { LeaveForecast.rate = response - ? context + ? (await context .read() - .getCurrentForecast(stage: selectTour.tour) + .getCurrentForecast(stage: selectTour!.tour)).rate : ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-']; setState(() { leaveForecast = response; @@ -64,13 +62,13 @@ class _ShowTourState extends State { Card( color: Colors.yellow, child: ListTile( - leading: Text(selectTour.tour), + leading: Text(selectTour!.tour), title: Text( - '${selectTour.matches.where((element) => element.started).length}/10 матчей'), + '${selectTour!.matches.where((element) => element.started).length}/10 матчей'), ), ), SizedBox(height: 20), - selectTour.matches.length == 10 + selectTour!.matches.length == 10 ? Column( children: [ Wrap( @@ -79,11 +77,11 @@ class _ShowTourState extends State { spacing: 10, runSpacing: 10, children: [ - ...selectTour.matches + ...selectTour!.matches .map((match) => MatchView(match: match)), ], ), - if (DateTime.now().isBefore(selectTour.deadline)) + if (DateTime.now().isBefore(selectTour!.deadline)) Column( children: [ SizedBox(height: 20), @@ -94,12 +92,12 @@ class _ShowTourState extends State { MaterialPageRoute>( builder: (BuildContext context) { return LeaveForecast( - tour: selectTour, + tour: selectTour!, ); }, ), ).then( - (List value) { + (List? value) { //context.read() //! отправка прогноза if (value != null) { @@ -134,7 +132,7 @@ class _ShowTourState extends State { Navigator.of(context).push( MaterialPageRoute>( builder: (BuildContext context) { - return SelectMatch(stage: selectTour.tour); + return SelectMatch(stage: selectTour!.tour); }, ), ).then( @@ -153,7 +151,7 @@ class _ShowTourState extends State { spacing: 10, runSpacing: 10, children: [ - ...selectTour.pair.map((pair) => MeetView(match: pair)), + ...selectTour!.pair.map((pair) => MeetView(match: pair)), ], ), ], diff --git a/team_c_f/lib/old/oldmain.dart b/team_c_f/lib/old/oldmain.dart new file mode 100644 index 0000000..2b47f2a --- /dev/null +++ b/team_c_f/lib/old/oldmain.dart @@ -0,0 +1,85 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +// import 'package:team_c_f/data/data.dart'; +// import 'package:team_c_f/data/shortmatch.dart'; +// import 'package:team_c_f/data/tournament.dart'; +// import 'package:team_c_f/page/home.dart'; +// import 'package:team_c_f/page/sign.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:onesignal_flutter/onesignal_flutter.dart'; + +Future main() async { + myApp(); +} + +myApp() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); // Инициализация Firebase + + OneSignal.shared.init('93b27d54-e442-4af5-86e4-a215faf20e3a', iOSSettings: { + OSiOSSettings.autoPrompt: false, + OSiOSSettings.inAppLaunchUrl: false + }); + OneSignal.shared + .setInFocusDisplayType(OSNotificationDisplayType.notification); + + runApp( + MultiProvider( + // Мультипровайдер, для упроощения взаимодействия с данными + providers: [ + // ChangeNotifierProvider( + // create: (context) => Account(), + // ), // Данные связанные с аутентификацией (гугл-вход и регистрация в приложении) + // ChangeNotifierProvider( + // create: (context) => Tournament(), + // ), // Данные полученные из Firebase + // ChangeNotifierProvider( + // create: (context) => DataMatch(), + // ), + ], + child: MaterialApp( + // theme: ThemeData( + // textTheme: TextTheme( + // bodyText2: TextStyle( + // color: Colors.black, + // fontWeight: FontWeight.normal, + // ), + // bodyText1: TextStyle( + // color: Colors.black, + // decoration: TextDecoration.lineThrough, + // fontWeight: FontWeight.normal, + // ), + // caption: TextStyle( + // color: Colors.green, + // fontWeight: FontWeight.w400, + // ), + // ), + // ), + home: SafeArea( + child: Page(), + ), + ), + ), + ); +} + +class Page extends StatefulWidget { + const Page({Key? key}) : super(key: key); + + @override + _PageState createState() => _PageState(); +} + +class _PageState extends State { + @override + Widget build(BuildContext context) { + return Container( + // child: context + // .watch() + // .registedInApp // Проверка зарегистрирован ли пользователь в приложении + // ? Homepage() // Домашняя страница приложения + // : Sign(), // Регистрация в приложении + вход в гугл + ); + } +} \ No newline at end of file diff --git a/team_c_f/lib/page/home.dart b/team_c_f/lib/old/page/home.dart similarity index 86% rename from team_c_f/lib/page/home.dart rename to team_c_f/lib/old/page/home.dart index f130359..2754ecf 100644 --- a/team_c_f/lib/page/home.dart +++ b/team_c_f/lib/old/page/home.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/currenttour.dart'; -import 'package:team_c_f/element/tour.dart'; -import 'package:team_c_f/view/emptyschedule.dart'; -import 'package:team_c_f/view/scorers.dart'; -import 'package:team_c_f/view/table.dart'; -import 'package:team_c_f/view/team.dart'; +import 'package:team_c_f/old/data/currenttour.dart'; +import 'package:team_c_f/old/element/tour.dart'; +import 'package:team_c_f/old/view/emptyschedule.dart'; +import 'package:team_c_f/old/view/scorers.dart'; +import 'package:team_c_f/old/view/table.dart'; +import 'package:team_c_f/old/view/team.dart'; import 'package:custom_navigation_bar/custom_navigation_bar.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/old/data/tournament.dart'; +import 'package:team_c_f/old/data/data.dart'; class Homepage extends StatefulWidget { // Класс отображающий домашнюю страницу с баром снизу - const Homepage({Key key}) : super(key: key); + const Homepage({Key? key}) : super(key: key); @override _HomepageState createState() => _HomepageState(); @@ -42,7 +42,7 @@ class _HomepageState extends State { : ShowTable() : selectedPage > 0 ? selectedPage == 2 - ? ShowTour(tour: current != null ? current.tour : null) + ? ShowTour(tour: current.tour) : ScheduleView() : TeamView(), bottomNavigationBar: CustomNavigationBar( diff --git a/team_c_f/lib/page/leaveforecast.dart b/team_c_f/lib/old/page/leaveforecast.dart similarity index 88% rename from team_c_f/lib/page/leaveforecast.dart rename to team_c_f/lib/old/page/leaveforecast.dart index 1d64348..cd73740 100644 --- a/team_c_f/lib/page/leaveforecast.dart +++ b/team_c_f/lib/old/page/leaveforecast.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/schedule.dart'; -import 'package:team_c_f/element/forecast.dart'; -import 'package:team_c_f/data/match.dart'; +import 'package:team_c_f/old/data/schedule.dart'; +import 'package:team_c_f/old/element/forecast.dart'; +import 'package:team_c_f/old/data/match.dart'; class LeaveForecast extends StatefulWidget { final Tour tour; - const LeaveForecast({Key key, this.tour}) : super(key: key); + const LeaveForecast({Key? key, required this.tour}) : super(key: key); static List rate = ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-']; diff --git a/team_c_f/lib/page/selectmatch.dart b/team_c_f/lib/old/page/selectmatch.dart similarity index 94% rename from team_c_f/lib/page/selectmatch.dart rename to team_c_f/lib/old/page/selectmatch.dart index 0bc6239..56bceef 100644 --- a/team_c_f/lib/page/selectmatch.dart +++ b/team_c_f/lib/old/page/selectmatch.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/shortmatch.dart'; -import 'package:team_c_f/servise/htmlparse.dart'; -import 'package:team_c_f/servise/make.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; +import 'package:team_c_f/old/servise/htmlparse.dart'; +import 'package:team_c_f/old/servise/make.dart'; import 'package:intl/intl.dart'; import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker; import 'package:http/http.dart' as http; @@ -10,7 +10,7 @@ import 'package:http/http.dart' as http; class SelectMatch extends StatefulWidget { // Отображение выбора 10 матчей на тур final String stage; - SelectMatch({Key key, @required this.stage}) : super(key: key); + SelectMatch({Key? key, required this.stage}) : super(key: key); @override _SelectMatchState createState() => _SelectMatchState(); diff --git a/team_c_f/lib/page/sign.dart b/team_c_f/lib/old/page/sign.dart similarity index 95% rename from team_c_f/lib/page/sign.dart rename to team_c_f/lib/old/page/sign.dart index d3ea08f..1a4b198 100644 --- a/team_c_f/lib/page/sign.dart +++ b/team_c_f/lib/old/page/sign.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/element/selectTeam.dart'; +import 'package:team_c_f/old/data/data.dart'; +import 'package:team_c_f/old/element/selectTeam.dart'; class Sign extends StatefulWidget { // Класс отображения страницы входа в Google-аккаунт и регистрации в приложении - Sign({Key key}) : super(key: key); + Sign({Key? key}) : super(key: key); @override _SignState createState() => _SignState(); diff --git a/team_c_f/lib/servise/auth.dart b/team_c_f/lib/old/servise/auth.dart similarity index 74% rename from team_c_f/lib/servise/auth.dart rename to team_c_f/lib/old/servise/auth.dart index 09f7b6d..8c6a4cf 100644 --- a/team_c_f/lib/servise/auth.dart +++ b/team_c_f/lib/old/servise/auth.dart @@ -4,16 +4,16 @@ import 'package:google_sign_in/google_sign_in.dart'; Future signInWithGoogle() async { // Выполнение входа в Google-аккаунт - final GoogleSignInAccount googleUser = await GoogleSignIn().signIn(); + final GoogleSignInAccount googleUser = (await GoogleSignIn().signIn())!; final GoogleSignInAuthentication googleAuth = await googleUser.authentication; - final GoogleAuthCredential credential = GoogleAuthProvider.credential( + final OAuthCredential credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); - return (await FirebaseAuth.instance.signInWithCredential(credential)).user; + return (await FirebaseAuth.instance.signInWithCredential(credential)).user!; } -Future signOutGoogle({BuildContext context}) async { +Future signOutGoogle({BuildContext? context}) async { // Выполнение выхода из Google-аккаунта FirebaseAuth.instance.signOut(); return GoogleSignIn().signOut().then((value) => true); diff --git a/team_c_f/lib/servise/htmlparse.dart b/team_c_f/lib/old/servise/htmlparse.dart similarity index 90% rename from team_c_f/lib/servise/htmlparse.dart rename to team_c_f/lib/old/servise/htmlparse.dart index 93ef346..8ae1bed 100644 --- a/team_c_f/lib/servise/htmlparse.dart +++ b/team_c_f/lib/old/servise/htmlparse.dart @@ -1,11 +1,10 @@ -import 'package:flutter/material.dart' as material; import 'package:html/dom.dart'; import 'package:html/parser.dart' show parse; -import 'package:team_c_f/data/shortmatch.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; List getMatchs({ - @material.required String body, // Html-текст страницы - @material.required String date, // Дата + required String body, // Html-текст страницы + required String date, // Дата }) { List m = []; Map> data = Map>(); diff --git a/team_c_f/lib/servise/make.dart b/team_c_f/lib/old/servise/make.dart similarity index 86% rename from team_c_f/lib/servise/make.dart rename to team_c_f/lib/old/servise/make.dart index 6af76e2..ace7bfd 100644 --- a/team_c_f/lib/servise/make.dart +++ b/team_c_f/lib/old/servise/make.dart @@ -1,10 +1,9 @@ -import 'package:flutter/widgets.dart'; -import 'package:team_c_f/data/shortmatch.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; import 'package:collection/collection.dart'; -import 'package:team_c_f/view/day.dart'; -import 'package:team_c_f/view/tournament.dart'; +import 'package:team_c_f/old/view/day.dart'; +import 'package:team_c_f/old/view/tournament.dart'; -List makeTournaments({List matches}) { +List makeTournaments({required List matches}) { // Функция группировки матчей по соревнованиям Map> gr = groupBy( matches, (obj) => obj.tournament); // Группировка матчей по соревнованиям @@ -70,7 +69,7 @@ String showTeam(int points) { : 'команд'); } -String showMatches({@required int teams, @required int circles}) { +String showMatches({required int teams, required int circles}) { int matches = (teams * (teams - 1) / 2).round() * circles; return matches.toString() + ' ' + @@ -81,7 +80,7 @@ String showMatches({@required int teams, @required int circles}) { : 'матчей'); } -String showTours({@required int teams, @required int circles}) { +String showTours({required int teams, required int circles}) { int tours = circles * (teams.isEven ? teams - 1 : teams); return tours.toString() + ' ' + @@ -93,12 +92,12 @@ String showTours({@required int teams, @required int circles}) { } int calculatePointPerMatch({ - @required String result, - @required String forecast, + required String result, + required String forecast, }) { // Фукнция подсчета очков за матч - List res = result.split('-').map((e) => int.parse(e)); - List forec = forecast.split('-').map((e) => int.parse(e)); + List res = result.split('-').map((e) => int.parse(e)).toList(); + List forec = forecast.split('-').map((e) => int.parse(e)).toList(); return res[0] - res[1] == forec[0] - forec[1] ? res[0] == forec[0] && res[1] == forec[1] ? 3 diff --git a/team_c_f/lib/servise/operationdb.dart b/team_c_f/lib/old/servise/operationdb.dart similarity index 84% rename from team_c_f/lib/servise/operationdb.dart rename to team_c_f/lib/old/servise/operationdb.dart index 2ae8823..0394929 100644 --- a/team_c_f/lib/servise/operationdb.dart +++ b/team_c_f/lib/old/servise/operationdb.dart @@ -1,11 +1,10 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:flutter/material.dart'; -import 'package:team_c_f/data/currenttour.dart'; -import 'package:team_c_f/data/forecast.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/schedule.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/data/match.dart'; +import 'package:team_c_f/old/data/currenttour.dart'; +import 'package:team_c_f/old/data/forecast.dart'; +import 'package:team_c_f/old/data/player.dart'; +import 'package:team_c_f/old/data/schedule.dart'; +import 'package:team_c_f/old/data/team.dart'; +import 'package:team_c_f/old/data/match.dart'; class DatabaseService { final CollectionReference currentCollection = @@ -42,7 +41,7 @@ class DatabaseService { ); } - Stream> getCurrentForecasts({@required String stage}) { + Stream> getCurrentForecasts({required String stage}) { // Получение всех прогнозов на текущий тур return forecastsCollection .where( @@ -76,7 +75,7 @@ class DatabaseService { ); } - Stream getTour({@required String stage}) { + Stream getTour({required String stage}) { // Получение информации о туре stage return scheduleCollection .where( @@ -106,7 +105,7 @@ class DatabaseService { ); } - Future userExists({@required String userId}) { + Future userExists({required String userId}) { // Проверка существует ли пользователь с указанным Google-аккаунтом return playersCollection .where('UserId', isEqualTo: userId) @@ -114,21 +113,21 @@ class DatabaseService { .then((value) => value.docs.length == 1); } - Future registrationPlayer({@required Player player}) { + Future registrationPlayer({required Player player}) { // Регистрация игрока return playersCollection .add(player.toMap()) .then((response) => player.docId = response.id); } - Future registrationTeam({@required Team team}) { + Future registrationTeam({required Team team}) { // Регистрация команды return teamsCollection .add(team.toMap()) .then((response) => team.docId = response.id); } - Future checkTeamName({@required String name}) { + Future checkTeamName({required String name}) { // Проверка названия команды на уникальность return teamsCollection .where('Title', isEqualTo: name) @@ -136,28 +135,28 @@ class DatabaseService { .then((response) => response.docs.length == 0); } - void updatePlayer({@required Player player}) { + void updatePlayer({required Player player}) { // Обновление информации об игроке playersCollection.doc(player.docId).update( player.toMap(), ); } - void updateTeam({@required Team team}) { + void updateTeam({required Team team}) { // Обновление информации о команде teamsCollection.doc(team.docId).update( team.toMap(), ); } - void addTour({@required Tour tour}) { + void addTour({required Tour tour}) { // Добавление тура на сервер scheduleCollection .add(tour.toMap()) .then((reaponse) => tour.docId = reaponse.id); } - void updateTour({@required Tour tour}) { + void updateTour({required Tour tour}) { // Обновление тура на сервере scheduleCollection.doc(tour.docId).update( tour.toMap(), @@ -172,8 +171,8 @@ class DatabaseService { //! Выше используется и не требует изменений Future checkForecast({ - @required String uid, - @required String stage, + required String uid, + required String stage, }) { return forecastsCollection .where( @@ -185,7 +184,7 @@ class DatabaseService { .then((QuerySnapshot response) => response.docs.length == 1); } - Future makeForecast({@required Forecast forecast}) async { + Future makeForecast({required Forecast forecast}) async { // Создание прогноза return forecastsCollection .add(forecast.toMap()) @@ -193,8 +192,8 @@ class DatabaseService { } Future getForecast({ - @required String uid, - @required String tour, + required String uid, + required String tour, }) async { // Получение прогноза указанного пользователя на указанный тур Query query = forecastsCollection @@ -204,7 +203,7 @@ class DatabaseService { (QuerySnapshot value) => value.docs .map( (DocumentSnapshot doc) => Forecast.fromJson( - json: doc.data(), + json: doc.data()!, docId: doc.id, ), ) @@ -212,14 +211,14 @@ class DatabaseService { ); } - Future> getForecasts({String tour}) async { + Future> getForecasts({required String tour}) async { // Получение всех прогноз на указанный тур Query query = forecastsCollection.where('Tour', isEqualTo: tour); return query.get().then( (QuerySnapshot value) => value.docs .map( (DocumentSnapshot doc) => Forecast.fromJson( - json: doc.data(), + json: doc.data()!, docId: doc.id, ), ) @@ -228,7 +227,7 @@ class DatabaseService { } //! Использовать для обновления результатов с сервера - Future> getResults({String tour}) { + Future> getResults({required String tour}) { // Получение результатов матчей return scheduleCollection .where( @@ -245,7 +244,7 @@ class DatabaseService { } //! Обновление результатов на сервера - void updateResults({Tour tour}) { + void updateResults({required Tour tour}) { // Обновление результатов матчей конкретного тура scheduleCollection.doc(tour.docId).update( tour.toMap(), diff --git a/team_c_f/lib/view/day.dart b/team_c_f/lib/old/view/day.dart similarity index 93% rename from team_c_f/lib/view/day.dart rename to team_c_f/lib/old/view/day.dart index 033ea3b..304e0e0 100644 --- a/team_c_f/lib/view/day.dart +++ b/team_c_f/lib/old/view/day.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/shortmatch.dart'; -import 'package:team_c_f/servise/make.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; +import 'package:team_c_f/old/servise/make.dart'; class DayView extends StatefulWidget { // Класс, отобращающий все соревнования, в которых есть матчи, в текущий день final String date; // Дата final List matches; // Список матчей для отображения const DayView({ - Key key, - @required this.date, - @required this.matches, + Key? key, + required this.date, + required this.matches, }) : super(key: key); @override diff --git a/team_c_f/lib/view/emptyschedule.dart b/team_c_f/lib/old/view/emptyschedule.dart similarity index 81% rename from team_c_f/lib/view/emptyschedule.dart rename to team_c_f/lib/old/view/emptyschedule.dart index b9b61c8..31361f2 100644 --- a/team_c_f/lib/view/emptyschedule.dart +++ b/team_c_f/lib/old/view/emptyschedule.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/element/createschedule.dart'; -import 'package:team_c_f/element/tour.dart'; -import 'package:team_c_f/view/schedule.dart'; +import 'package:team_c_f/old/data/tournament.dart'; +import 'package:team_c_f/old/element/createschedule.dart'; +import 'package:team_c_f/old/element/tour.dart'; +import 'package:team_c_f/old/view/schedule.dart'; class ScheduleView extends StatefulWidget { // Если расписание отсутствует - const ScheduleView({Key key}) : super(key: key); + const ScheduleView({Key? key}) : super(key: key); @override _ScheduleViewState createState() => _ScheduleViewState(); diff --git a/team_c_f/lib/view/forecast.dart b/team_c_f/lib/old/view/forecast.dart similarity index 86% rename from team_c_f/lib/view/forecast.dart rename to team_c_f/lib/old/view/forecast.dart index 2d33d45..4f2f69a 100644 --- a/team_c_f/lib/view/forecast.dart +++ b/team_c_f/lib/old/view/forecast.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class MakeForecast extends StatelessWidget { // Класс, позволяющий сделать прогноз на следующий тур - const MakeForecast({Key key}) : super(key: key); + const MakeForecast({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/view/match.dart b/team_c_f/lib/old/view/match.dart similarity index 87% rename from team_c_f/lib/view/match.dart rename to team_c_f/lib/old/view/match.dart index d661277..0d977b5 100644 --- a/team_c_f/lib/view/match.dart +++ b/team_c_f/lib/old/view/match.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/shortmatch.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; class MatchView extends StatefulWidget { // Класс, отображащий информацию о матче, при выборе матчей final ShortMatch match; // Краткая информация о матче const MatchView({ - Key key, - @required this.match, + Key? key, + required this.match, }) : super(key: key); @override @@ -33,7 +33,7 @@ class _MatchViewState extends State { value: selected, title: Text('$time. $home - $away'), onChanged: (a) { - context.read().selectMatch(widget.match, a); + context.read().selectMatch(widget.match, a!); }, ), ); diff --git a/team_c_f/lib/view/meet.dart b/team_c_f/lib/old/view/meet.dart similarity index 100% rename from team_c_f/lib/view/meet.dart rename to team_c_f/lib/old/view/meet.dart diff --git a/team_c_f/lib/view/schedule.dart b/team_c_f/lib/old/view/schedule.dart similarity index 86% rename from team_c_f/lib/view/schedule.dart rename to team_c_f/lib/old/view/schedule.dart index 221c04e..5f8e8f7 100644 --- a/team_c_f/lib/view/schedule.dart +++ b/team_c_f/lib/old/view/schedule.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/tournament.dart'; -import 'package:team_c_f/element/schedule.dart'; +import 'package:team_c_f/old/data/tournament.dart'; +import 'package:team_c_f/old/element/schedule.dart'; class ShowSchedules extends StatefulWidget { // Класс, отображающий результаты тура, по умолчанию текущего - const ShowSchedules({Key key}) : super(key: key); + const ShowSchedules({Key? key}) : super(key: key); @override _ShowSchedulesState createState() => _ShowSchedulesState(); diff --git a/team_c_f/lib/view/scorers.dart b/team_c_f/lib/old/view/scorers.dart similarity index 85% rename from team_c_f/lib/view/scorers.dart rename to team_c_f/lib/old/view/scorers.dart index bfd5387..ecbfef8 100644 --- a/team_c_f/lib/view/scorers.dart +++ b/team_c_f/lib/old/view/scorers.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; class ShowScorers extends StatelessWidget { // Класс, отображающий список бомбардиров - const ShowScorers({Key key}) : super(key: key); + const ShowScorers({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/view/table.dart b/team_c_f/lib/old/view/table.dart similarity index 91% rename from team_c_f/lib/view/table.dart rename to team_c_f/lib/old/view/table.dart index 4dbfa6d..1794155 100644 --- a/team_c_f/lib/view/table.dart +++ b/team_c_f/lib/old/view/table.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; class ShowTable extends StatelessWidget { // Класс, отображающий туры, с возможностью их выбора для просмотра - const ShowTable({Key key}) : super(key: key); + const ShowTable({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/view/team.dart b/team_c_f/lib/old/view/team.dart similarity index 88% rename from team_c_f/lib/view/team.dart rename to team_c_f/lib/old/view/team.dart index 6a83cc4..a8a77c2 100644 --- a/team_c_f/lib/view/team.dart +++ b/team_c_f/lib/old/view/team.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/tournament.dart'; +import 'package:team_c_f/old/data/data.dart'; +import 'package:team_c_f/old/data/tournament.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/element/notconfirmedplayer.dart'; -import 'package:team_c_f/element/selectTeam.dart'; -import 'package:team_c_f/element/team.dart'; +import 'package:team_c_f/old/element/notconfirmedplayer.dart'; +import 'package:team_c_f/old/element/selectTeam.dart'; +import 'package:team_c_f/old/element/team.dart'; class TeamView extends StatefulWidget { // Класс, отображающий информацию о команде участника - const TeamView({Key key}) : super(key: key); + const TeamView({Key? key}) : super(key: key); @override _TeamViewState createState() => _TeamViewState(); @@ -17,7 +17,7 @@ class TeamView extends StatefulWidget { class _TeamViewState extends State { bool capitan = false; TextEditingController teamController = TextEditingController(); - String teamSelect; + String? teamSelect; @override Widget build(BuildContext context) { return Container( @@ -75,7 +75,7 @@ class _TeamViewState extends State { .watch() .allPlayers .where((player) => (!player.confirmed && - player.team == context.read().myTeam.title)) + player.team == context.read().myTeam!.title)) .map( (p) => PlayerToConfirm(player: p), ), @@ -83,7 +83,7 @@ class _TeamViewState extends State { if (context.read().myTeam != null) ShowTeam( // Показ информации о моей команде - team: context.read().myTeam, + team: context.read().myTeam!, ) ], ), diff --git a/team_c_f/lib/view/tournament.dart b/team_c_f/lib/old/view/tournament.dart similarity index 92% rename from team_c_f/lib/view/tournament.dart rename to team_c_f/lib/old/view/tournament.dart index a5aa59a..0bef1ed 100644 --- a/team_c_f/lib/view/tournament.dart +++ b/team_c_f/lib/old/view/tournament.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/shortmatch.dart'; -import 'package:team_c_f/view/match.dart'; +import 'package:team_c_f/old/data/shortmatch.dart'; +import 'package:team_c_f/old/view/match.dart'; class TournamentView extends StatefulWidget { // Класс, отображения соревнований, в которых выбираются матчи @@ -8,9 +8,9 @@ class TournamentView extends StatefulWidget { final String tournament; // Название соревнования const TournamentView({ // Конструктор - Key key, - @required this.tournament, - @required this.matches, + Key? key, + required this.tournament, + required this.matches, }) : super(key: key); @override diff --git a/team_c_f/lib/pages/login.dart b/team_c_f/lib/pages/login.dart new file mode 100644 index 0000000..1a4b198 --- /dev/null +++ b/team_c_f/lib/pages/login.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/old/data/data.dart'; +import 'package:team_c_f/old/element/selectTeam.dart'; + +class Sign extends StatefulWidget { + // Класс отображения страницы входа в Google-аккаунт и регистрации в приложении + Sign({Key? key}) : super(key: key); + + @override + _SignState createState() => _SignState(); +} + +class _SignState extends State { + TextEditingController nameController = + TextEditingController(); // Контроллер для ввода имени участника + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + height: double.infinity, + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + context + .read() + .changeSignIn(); // Изменение состояния входа в Google-аккаунт + }, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text(context.watch().signIn ? 'Выйти' : 'Войти'), + SizedBox(width: 10), + Image( + image: AssetImage('assets/images/google.png'), + fit: BoxFit.fill, + height: 30, + ), + ], + ), + ), + Text( + context.watch().signIn + ? 'Вход выполнен, осталось совсем чуть чуть' + : 'Необходимо войти в аккаунт', + textAlign: TextAlign.center, + ), + SizedBox( + height: 20, + ), + Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(16.0), + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Введите ваше имя и фамилию', + style: TextStyle( + color: Colors.white, + ), + ), + ), + TextField( + decoration: + InputDecoration(fillColor: Colors.white, filled: true), + // Ввод имени участника + controller: nameController, + onChanged: (str) { + setState(() {}); + }, + textAlign: TextAlign.center, + ), + ], + ), + ), + SelectTeam( + message: 'Зарегистрироваться', + name: nameController.text.trim(), + ), + SizedBox(height: 100,), + ], + ), + ), + ); + } +} diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart new file mode 100644 index 0000000..c62e500 --- /dev/null +++ b/team_c_f/lib/store/login/login.dart @@ -0,0 +1,80 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; +import 'package:mobx/mobx.dart'; + +part 'login.g.dart'; + +final GoogleSignIn _googleSignIn = GoogleSignIn(); +final FirebaseAuth _auth = FirebaseAuth.instance; + +class Login = LoginBase with _$Login; + +abstract class LoginBase with Store { + LoginBase() { + googleLogin(); + } + + @observable + bool login = false; + + @observable + String userName = 'No user'; + + @action + void changeName(String text) { + userName = text.trim(); + } + + @observable + ObservableFuture loginStatus = ObservableFuture.value(false); + + @action + void changeLoginStatus(dynamic status) { + loginStatus = status; + } + + @computed + bool get updatedLoginStatus => loginStatus.value!; + + @action + Future googleLogin() async { + GoogleSignInAccount gUser = await getGoogleUser(); + GoogleSignInAuthentication googAuth = await gUser.authentication; + User? user; + + final AuthCredential credential = GoogleAuthProvider.credential( + idToken: googAuth.idToken, + accessToken: googAuth.accessToken, + ); + UserCredential userCredential = + await _auth.signInWithCredential(credential); + + user = userCredential.user; + + if (user?.uid != null) { + loginStatus = ObservableFuture.value(true); + } else { + loginStatus = ObservableFuture.value(false); + } + return Future.value(true); + } + + @action + Future logoutAccount() async { + _googleSignIn.signOut(); + _auth.signOut(); + loginStatus = ObservableFuture.value(false); + return await Future.value(true); + } + + Future getGoogleUser() async { + GoogleSignInAccount? googleUser = _googleSignIn.currentUser; + if (googleUser == null) { + googleUser = await _googleSignIn.signInSilently(); + } + if (googleUser == null) { + googleUser = await _googleSignIn.signIn(); + } + return googleUser; + } +} diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart new file mode 100644 index 0000000..a2b71ae --- /dev/null +++ b/team_c_f/lib/store/login/login.g.dart @@ -0,0 +1,112 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$Login on LoginBase, Store { + Computed? _$updatedLoginStatusComputed; + + @override + bool get updatedLoginStatus => (_$updatedLoginStatusComputed ??= + Computed(() => super.updatedLoginStatus, + name: 'LoginBase.updatedLoginStatus')) + .value; + + final _$loginAtom = Atom(name: 'LoginBase.login'); + + @override + bool get login { + _$loginAtom.reportRead(); + return super.login; + } + + @override + set login(bool value) { + _$loginAtom.reportWrite(value, super.login, () { + super.login = value; + }); + } + + final _$userNameAtom = Atom(name: 'LoginBase.userName'); + + @override + String get userName { + _$userNameAtom.reportRead(); + return super.userName; + } + + @override + set userName(String value) { + _$userNameAtom.reportWrite(value, super.userName, () { + super.userName = value; + }); + } + + final _$loginStatusAtom = Atom(name: 'LoginBase.loginStatus'); + + @override + ObservableFuture get loginStatus { + _$loginStatusAtom.reportRead(); + return super.loginStatus; + } + + @override + set loginStatus(ObservableFuture value) { + _$loginStatusAtom.reportWrite(value, super.loginStatus, () { + super.loginStatus = value; + }); + } + + final _$googleLoginAsyncAction = AsyncAction('LoginBase.googleLogin'); + + @override + Future googleLogin() { + return _$googleLoginAsyncAction.run(() => super.googleLogin()); + } + + final _$logoutAccountAsyncAction = AsyncAction('LoginBase.logoutAccount'); + + @override + Future logoutAccount() { + return _$logoutAccountAsyncAction.run(() => super.logoutAccount()); + } + + final _$LoginBaseActionController = ActionController(name: 'LoginBase'); + + @override + void changeName(String text) { + final _$actionInfo = + _$LoginBaseActionController.startAction(name: 'LoginBase.changeName'); + try { + return super.changeName(text); + } finally { + _$LoginBaseActionController.endAction(_$actionInfo); + } + } + + @override + void changeLoginStatus(dynamic status) { + final _$actionInfo = _$LoginBaseActionController.startAction( + name: 'LoginBase.changeLoginStatus'); + try { + return super.changeLoginStatus(status); + } finally { + _$LoginBaseActionController.endAction(_$actionInfo); + } + } + + @override + String toString() { + return ''' +login: ${login}, +userName: ${userName}, +loginStatus: ${loginStatus}, +updatedLoginStatus: ${updatedLoginStatus} + '''; + } +} diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index 9e67e3d..ada62ed 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -57,6 +57,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" build_resolvers: dependency: transitive description: @@ -64,6 +78,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.0" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.0.5" carousel_slider: dependency: "direct main" description: @@ -85,6 +127,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" cli_util: dependency: transitive description: @@ -105,21 +154,28 @@ packages: name: cloud_firestore url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.6" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.0.2" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.6" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" collection: dependency: transitive description: @@ -203,28 +259,28 @@ packages: name: firebase_auth url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.1" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.1.1" firebase_auth_web: dependency: transitive description: name: firebase_auth_web url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.7" firebase_core: dependency: transitive description: name: firebase_core url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" firebase_core_platform_interface: dependency: transitive description: @@ -239,6 +295,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" flutter: dependency: "direct main" description: flutter @@ -267,7 +330,7 @@ packages: name: fluttertoast url: "https://pub.dartlang.org" source: hosted - version: "8.0.3" + version: "8.0.6" glob: dependency: transitive description: @@ -281,7 +344,7 @@ packages: name: google_sign_in url: "https://pub.dartlang.org" source: hosted - version: "5.0.1" + version: "5.0.2" google_sign_in_platform_interface: dependency: transitive description: @@ -317,6 +380,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" http_parser: dependency: transitive description: @@ -331,6 +401,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.17.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" js: dependency: transitive description: @@ -338,6 +415,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.1" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.1" logging: dependency: transitive description: @@ -359,6 +450,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" mobx: dependency: "direct main" description: @@ -436,13 +534,34 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" quiver: dependency: transitive description: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter @@ -504,6 +623,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.19" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" typed_data: dependency: transitive description: @@ -525,6 +651,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" yaml: dependency: transitive description: diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index a0a2c62..3729168 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: @@ -45,8 +45,10 @@ dependencies: flutter_mobx: ^2.0.0 dev_dependencies: + build_runner: ^2.0.1 mobx_codegen: ^2.0.1+3 - + json_serializable: ^4.1.1 + flutter_test: sdk: flutter From 6769bc23b678b1084192afd36bfcc82448265e30 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 26 Apr 2021 20:11:46 +0300 Subject: [PATCH 04/24] 2 Store --- team_c_f/lib/components/login.dart | 10 +- team_c_f/lib/components/selectteam.dart | 290 ++++++++---------- team_c_f/lib/main.dart | 16 +- team_c_f/lib/old/oldmain.dart | 10 +- team_c_f/lib/old/page/selectmatch.dart | 1 + team_c_f/lib/servises/login.dart | 16 + team_c_f/lib/store/login/login.dart | 5 +- team_c_f/lib/store/login/login.g.dart | 6 +- team_c_f/lib/store/selectteam/selectteam.dart | 31 ++ .../lib/store/selectteam/selectteam.g.dart | 99 ++++++ team_c_f/pubspec.lock | 2 +- team_c_f/pubspec.yaml | 2 +- 12 files changed, 291 insertions(+), 197 deletions(-) create mode 100644 team_c_f/lib/servises/login.dart create mode 100644 team_c_f/lib/store/selectteam/selectteam.dart create mode 100644 team_c_f/lib/store/selectteam/selectteam.g.dart diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart index 088cbdf..400e062 100644 --- a/team_c_f/lib/components/login.dart +++ b/team_c_f/lib/components/login.dart @@ -8,7 +8,7 @@ import 'package:team_c_f/store/login/login.dart'; class LoginView extends StatelessWidget { @override Widget build(BuildContext context) { - final Login login = context.read().login!; + final Login login = Provider.of(context); return Container( height: double.infinity, width: double.infinity, @@ -20,7 +20,7 @@ class LoginView extends StatelessWidget { builder: (_) => ElevatedButton( onPressed: () { login.updatedLoginStatus - ? login.logoutAccount() + ? login.googleLogout() : login.googleLogin(); }, child: Row( @@ -81,9 +81,9 @@ class LoginView extends StatelessWidget { ), ), Observer( - builder: (_) => SelectTeam( - message: 'Зарегистрироваться', - name: login.userName, + builder: (_) => SelectTeamView( + selectTeam: Provider.of(context).selectTeam, + name: '', ), ), ], diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index 9dc9973..d52cc9f 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -3,26 +3,23 @@ import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/data/singledata/login.dart'; +import 'package:team_c_f/servises/login.dart'; import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/store/selectteam/selectteam.dart'; -class SelectTeam extends StatefulWidget { +class SelectTeamView extends StatelessWidget { // Класс отображения выбора команды или регистрации новой - final String message; final String name; - SelectTeam({Key? key, required this.message, required this.name}) : super(key: key); + final SelectTeam selectTeam; - @override - _SelectTeamState createState() => _SelectTeamState(); -} - -class _SelectTeamState extends State { - TextEditingController teamController = TextEditingController(); - String? teamSelect; - bool capitan = false; + const SelectTeamView({ + Key? key, + required this.name, + required this.selectTeam, + }) : super(key: key); @override Widget build(BuildContext context) { - final Login? login = context.read().login; return Column( children: [ Container( @@ -32,172 +29,125 @@ class _SelectTeamState extends State { color: Colors.blue, borderRadius: BorderRadius.circular(16.0), ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Checkbox( - // Чекбокс для капитанов - value: capitan, - checkColor: Colors.blue, - activeColor: Colors.white, - onChanged: (value) { - setState( - () { - capitan = value!; - }, - ); - }, - ), - Text( - 'Я капитан команды', - style: TextStyle( - color: Colors.white, + child: Observer( + builder: (_) => Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Checkbox( + // Чекбокс для капитанов + value: selectTeam.capitan, + checkColor: Colors.blue, + activeColor: Colors.white, + onChanged: selectTeam.changeCapitan, ), - ), - ], - ), - Container( - child: capitan - ? Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - 'Введите название вашей команды', - style: TextStyle( - color: Colors.white, - ), - ), - ), - TextField( + Text( + 'Я капитан команды', + style: TextStyle( + color: Colors.white, + ), + ), + ], + ), + Container( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + selectTeam.capitan + ? 'Введите название вашей команды' + : 'Выбери команду', + style: TextStyle( + color: Colors.white, + ), + ), + ), + selectTeam.capitan + ? TextField( // Ввод названия команды для капитана decoration: InputDecoration( fillColor: Colors.white, filled: true), - controller: teamController, - onChanged: (name) { - setState(() {}); - }, - textAlign: TextAlign.center, - ), - ], - ) - : false // Проверка существуют ли команды, чтобы в них зарегистрироваться - ? Column( - // Для пустого списка - children: [ - Text( - 'Ни одной доступной команды нет', - style: TextStyle( - color: Colors.white, - ), + onChanged: selectTeam.changeTeam, + controller: TextEditingController.fromValue( + TextEditingValue( + text: selectTeam.lastTeamName, + selection: TextSelection.collapsed( + offset: selectTeam.lastTeamName.length), ), - Text( - 'Можешь создать команду сам \u261d', - style: TextStyle( - color: Colors.white, - ), - ) - ], + ), + textAlign: TextAlign.center, ) - : Column( - // Для непустого списка - children: [ - Observer( - builder: (_) => Text( - login!.userName, - //'Выбери свою команду', - style: TextStyle( - color: Colors.white, - ), - ), - ), - // DropdownButton( - // value: teamSelect, - // onChanged: (newName) { - // setState(() { - // teamSelect = newName; - // }); - // }, - // items: [ - // ...context - // .watch() - // .allTeamNames - // .map>( - // (String team) => DropdownMenuItem( - // child: Text(team), - // value: team, - // ), - // ) - // .toList(), - // ], - // ), - ], - ), - ), - ], + : Text('Список команд'), + ], + ) + // : LoginService().checkTeamName(name: login.teamName) // Проверка существуют ли команды, чтобы в них зарегистрироваться + // ? Column( + // // Для пустого списка + // children: [ + // Text( + // 'Ни одной доступной команды нет', + // style: TextStyle( + // color: Colors.white, + // ), + // ), + // Text( + // 'Можешь создать команду сам \u261d', + // style: TextStyle( + // color: Colors.white, + // ), + // ) + // ], + // ) + // : Column( + // // Для непустого списка + // children: [ + // Observer( + // builder: (_) => Text( + // login.userName, + // //'Выбери свою команду', + // style: TextStyle( + // color: Colors.white, + // ), + // ), + // ), + // // DropdownButton( + // // value: teamSelect, + // // onChanged: (newName) { + // // setState(() { + // // teamSelect = newName; + // // }); + // // }, + // // items: [ + // // ...context + // // .watch() + // // .allTeamNames + // // .map>( + // // (String team) => DropdownMenuItem( + // // child: Text(team), + // // value: team, + // // ), + // // ) + // // .toList(), + // // ], + // // ), + // ], + // ), + ), + ], + ), ), ), - // ElevatedButton( - // // Кнопка регистрации - // style: ButtonStyle( - // backgroundColor: MaterialStateProperty.all(Colors.green), - // ), - // onPressed: context - // .watch() - // .signIn && // Проверка входа в Google-аккаунт - // ((capitan && // Проверка для капитана - // teamController.text - // .trim() - // .isNotEmpty) || // Проверка пустое ли название команды - // (!capitan && // Проверки для некапитанов - // context - // .watch() - // .allTeamNames - // .isNotEmpty && // или список команд должен быть не пустым - // teamSelect != null)) // и команда должна быть выбрана - // ? () async { - // if (capitan && - // !(await DatabaseService().checkTeamName( - // // Проверка уникальности имени команды - // name: teamController.text.trim()))) { - // Fluttertoast.showToast( - // msg: 'Команда с таким названием уже зарегистрирована', - // toastLength: Toast.LENGTH_LONG, - // ); - // } else { - // context - // .read() - // .registrationPlayer( - // // Регистрация игрока - // uid: context.read().userId, - // capitan: capitan, - // name: widget.name, - // team: - // capitan ? teamController.text.trim() : teamSelect, - // ) - // .then((value) => context.read().registedUser()) - // .then((value) { - // if (capitan) // Если капитан, то необходимо зарегистрировать команду - // context // Регистрация команды - // .read() - // .registrationTeam( - // title: teamController.text.trim()); - // context - // .read() - // .initMeAndMyTeam(uid: context.read().userId); - // }); - // } - // } // Функция регистрации - // : null, - // child: Text(capitan ? 'Зарегистрировать команду' : widget.message), - // ), - ElevatedButton( - onPressed: () { - Fluttertoast.showToast(msg: 'Name is ' + widget.name); - }, - child: Text('Show name'), + Observer( + builder: (_) => ElevatedButton( + // Кнопка регистрации + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.green), + ), + onPressed: selectTeam.capitan ? () {} : null, + child: Text(selectTeam.capitan ? 'Зарегистрировать команду' : ''), + ), ), ], ); diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart index 7a48fb2..e9c3c5f 100644 --- a/team_c_f/lib/main.dart +++ b/team_c_f/lib/main.dart @@ -4,6 +4,7 @@ import 'package:onesignal_flutter/onesignal_flutter.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/components/login.dart'; import 'package:team_c_f/data/singledata/login.dart'; +import 'package:team_c_f/store/login/login.dart'; Future main() async { myApp(); @@ -13,12 +14,7 @@ myApp() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // Инициализация Firebase - OneSignal.shared.init('93b27d54-e442-4af5-86e4-a215faf20e3a', iOSSettings: { - OSiOSSettings.autoPrompt: false, - OSiOSSettings.inAppLaunchUrl: false - }); - OneSignal.shared - .setInFocusDisplayType(OSNotificationDisplayType.notification); + OneSignal.shared.setAppId('93b27d54-e442-4af5-86e4-a215faf20e3a'); runApp(LoginPage()); } @@ -27,8 +23,10 @@ class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - home: ChangeNotifierProvider( - create: (_) => DataLogin(), + home: MultiProvider( + providers: [ + Provider(create: (_) => Login()), + ], child: SafeArea( child: Scaffold( body: LoginView(), @@ -37,4 +35,4 @@ class LoginPage extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/team_c_f/lib/old/oldmain.dart b/team_c_f/lib/old/oldmain.dart index 2b47f2a..3d9939e 100644 --- a/team_c_f/lib/old/oldmain.dart +++ b/team_c_f/lib/old/oldmain.dart @@ -7,6 +7,7 @@ import 'package:provider/provider.dart'; // import 'package:team_c_f/page/home.dart'; // import 'package:team_c_f/page/sign.dart'; import 'package:firebase_core/firebase_core.dart'; +// ignore: import_of_legacy_library_into_null_safe import 'package:onesignal_flutter/onesignal_flutter.dart'; Future main() async { @@ -17,13 +18,8 @@ myApp() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // Инициализация Firebase - OneSignal.shared.init('93b27d54-e442-4af5-86e4-a215faf20e3a', iOSSettings: { - OSiOSSettings.autoPrompt: false, - OSiOSSettings.inAppLaunchUrl: false - }); - OneSignal.shared - .setInFocusDisplayType(OSNotificationDisplayType.notification); - + OneSignal.shared.setAppId('93b27d54-e442-4af5-86e4-a215faf20e3a'); + runApp( MultiProvider( // Мультипровайдер, для упроощения взаимодействия с данными diff --git a/team_c_f/lib/old/page/selectmatch.dart b/team_c_f/lib/old/page/selectmatch.dart index 56bceef..c2548dd 100644 --- a/team_c_f/lib/old/page/selectmatch.dart +++ b/team_c_f/lib/old/page/selectmatch.dart @@ -4,6 +4,7 @@ import 'package:team_c_f/old/data/shortmatch.dart'; import 'package:team_c_f/old/servise/htmlparse.dart'; import 'package:team_c_f/old/servise/make.dart'; import 'package:intl/intl.dart'; +// ignore: import_of_legacy_library_into_null_safe import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker; import 'package:http/http.dart' as http; diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart new file mode 100644 index 0000000..c73a1fd --- /dev/null +++ b/team_c_f/lib/servises/login.dart @@ -0,0 +1,16 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +class LoginService { + final CollectionReference playersCollection = + FirebaseFirestore.instance.collection('players'); + final CollectionReference teamsCollection = + FirebaseFirestore.instance.collection('teams'); + + Future checkTeamName({required String name}) { + // Проверка названия команды на уникальность + return teamsCollection + .where('Title', isEqualTo: name) + .get() + .then((response) => response.docs.length == 0); + } +} diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index c62e500..699c4bc 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -1,6 +1,7 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:mobx/mobx.dart'; +import 'package:team_c_f/store/selectteam/selectteam.dart'; part 'login.g.dart'; @@ -25,6 +26,8 @@ abstract class LoginBase with Store { userName = text.trim(); } + final selectTeam = SelectTeam(); + @observable ObservableFuture loginStatus = ObservableFuture.value(false); @@ -60,7 +63,7 @@ abstract class LoginBase with Store { } @action - Future logoutAccount() async { + Future googleLogout() async { _googleSignIn.signOut(); _auth.signOut(); loginStatus = ObservableFuture.value(false); diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart index a2b71ae..b794888 100644 --- a/team_c_f/lib/store/login/login.g.dart +++ b/team_c_f/lib/store/login/login.g.dart @@ -69,11 +69,11 @@ mixin _$Login on LoginBase, Store { return _$googleLoginAsyncAction.run(() => super.googleLogin()); } - final _$logoutAccountAsyncAction = AsyncAction('LoginBase.logoutAccount'); + final _$googleLogoutAsyncAction = AsyncAction('LoginBase.googleLogout'); @override - Future logoutAccount() { - return _$logoutAccountAsyncAction.run(() => super.logoutAccount()); + Future googleLogout() { + return _$googleLogoutAsyncAction.run(() => super.googleLogout()); } final _$LoginBaseActionController = ActionController(name: 'LoginBase'); diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart new file mode 100644 index 0000000..b1f0f9e --- /dev/null +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -0,0 +1,31 @@ +import 'package:mobx/mobx.dart'; +import 'package:team_c_f/servises/login.dart'; +part 'selectteam.g.dart'; + +class SelectTeam = _SelectTeamBase with _$SelectTeam; + +abstract class _SelectTeamBase with Store { + + @observable + String teamName = 'No team'; + + @action + void changeTeam(String text){ + teamName = text.trim(); + } + + @observable + String lastTeamName = ''; + + @computed + Future get availableTeamName async { return await LoginService().checkTeamName(name: teamName);} + + @observable + bool capitan = false; + + @action + void changeCapitan(bool? value){ + capitan = value!; + lastTeamName = teamName; + } +} \ No newline at end of file diff --git a/team_c_f/lib/store/selectteam/selectteam.g.dart b/team_c_f/lib/store/selectteam/selectteam.g.dart new file mode 100644 index 0000000..9aa9e49 --- /dev/null +++ b/team_c_f/lib/store/selectteam/selectteam.g.dart @@ -0,0 +1,99 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'selectteam.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$SelectTeam on _SelectTeamBase, Store { + Computed>? _$availableTeamNameComputed; + + @override + Future get availableTeamName => (_$availableTeamNameComputed ??= + Computed>(() => super.availableTeamName, + name: '_SelectTeamBase.availableTeamName')) + .value; + + final _$teamNameAtom = Atom(name: '_SelectTeamBase.teamName'); + + @override + String get teamName { + _$teamNameAtom.reportRead(); + return super.teamName; + } + + @override + set teamName(String value) { + _$teamNameAtom.reportWrite(value, super.teamName, () { + super.teamName = value; + }); + } + + final _$lastTeamNameAtom = Atom(name: '_SelectTeamBase.lastTeamName'); + + @override + String get lastTeamName { + _$lastTeamNameAtom.reportRead(); + return super.lastTeamName; + } + + @override + set lastTeamName(String value) { + _$lastTeamNameAtom.reportWrite(value, super.lastTeamName, () { + super.lastTeamName = value; + }); + } + + final _$capitanAtom = Atom(name: '_SelectTeamBase.capitan'); + + @override + bool get capitan { + _$capitanAtom.reportRead(); + return super.capitan; + } + + @override + set capitan(bool value) { + _$capitanAtom.reportWrite(value, super.capitan, () { + super.capitan = value; + }); + } + + final _$_SelectTeamBaseActionController = + ActionController(name: '_SelectTeamBase'); + + @override + void changeTeam(String text) { + final _$actionInfo = _$_SelectTeamBaseActionController.startAction( + name: '_SelectTeamBase.changeTeam'); + try { + return super.changeTeam(text); + } finally { + _$_SelectTeamBaseActionController.endAction(_$actionInfo); + } + } + + @override + void changeCapitan(bool? value) { + final _$actionInfo = _$_SelectTeamBaseActionController.startAction( + name: '_SelectTeamBase.changeCapitan'); + try { + return super.changeCapitan(value); + } finally { + _$_SelectTeamBaseActionController.endAction(_$actionInfo); + } + } + + @override + String toString() { + return ''' +teamName: ${teamName}, +lastTeamName: ${lastTeamName}, +capitan: ${capitan}, +availableTeamName: ${availableTeamName} + '''; + } +} diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index ada62ed..bb84dc6 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -484,7 +484,7 @@ packages: name: onesignal_flutter url: "https://pub.dartlang.org" source: hosted - version: "2.6.3" + version: "3.0.0-beta2" package_config: dependency: transitive description: diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index 3729168..da9ad43 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -40,7 +40,7 @@ dependencies: google_sign_in: ^5.0.1 fluttertoast: ^8.0.3 adaptive_dialog: ^0.10.0+5 - onesignal_flutter: ^2.6.3 + onesignal_flutter: ^3.0.0-beta2 mobx: ^2.0.1 flutter_mobx: ^2.0.0 From a934b81063937a75e599e05d136040cfb49e7e94 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 26 Apr 2021 23:18:03 +0300 Subject: [PATCH 05/24] =?UTF-8?q?LoginPage=20=D0=B2=20=D0=BE=D1=82=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/login.dart | 14 ++- team_c_f/lib/components/selectteam.dart | 84 ++++++++------- team_c_f/lib/data/player.dart | 16 +++ team_c_f/lib/data/singledata/login.dart | 11 -- team_c_f/lib/data/team.dart | 18 ++++ team_c_f/lib/main.dart | 23 +--- team_c_f/lib/pages/login.dart | 101 +++--------------- team_c_f/lib/servises/login.dart | 16 --- team_c_f/lib/servises/selectteam.dart | 37 +++++++ team_c_f/lib/store/login/login.dart | 9 +- team_c_f/lib/store/login/login.g.dart | 16 --- team_c_f/lib/store/selectteam/selectteam.dart | 52 +++++++-- .../lib/store/selectteam/selectteam.g.dart | 52 +++++++-- 13 files changed, 233 insertions(+), 216 deletions(-) create mode 100644 team_c_f/lib/data/player.dart delete mode 100644 team_c_f/lib/data/singledata/login.dart create mode 100644 team_c_f/lib/data/team.dart create mode 100644 team_c_f/lib/servises/selectteam.dart diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart index 400e062..7fbd9de 100644 --- a/team_c_f/lib/components/login.dart +++ b/team_c_f/lib/components/login.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/components/selectteam.dart'; -import 'package:team_c_f/data/singledata/login.dart'; import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/store/selectteam/selectteam.dart'; class LoginView extends StatelessWidget { @override @@ -81,10 +81,14 @@ class LoginView extends StatelessWidget { ), ), Observer( - builder: (_) => SelectTeamView( - selectTeam: Provider.of(context).selectTeam, - name: '', - ), + builder: (_) { + SelectTeam selectTeam = Provider.of(context).selectTeam; + selectTeam.userName = Provider.of(context).userName; + selectTeam.uid = Provider.of(context).uid; + return SelectTeamView( + selectTeam: selectTeam, + ); + }, ), ], ), diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index d52cc9f..f41de17 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -1,25 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/data/singledata/login.dart'; -import 'package:team_c_f/servises/login.dart'; -import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; class SelectTeamView extends StatelessWidget { // Класс отображения выбора команды или регистрации новой - final String name; final SelectTeam selectTeam; const SelectTeamView({ Key? key, - required this.name, required this.selectTeam, }) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context) { return Column( children: [ Container( @@ -29,28 +23,30 @@ class SelectTeamView extends StatelessWidget { color: Colors.blue, borderRadius: BorderRadius.circular(16.0), ), - child: Observer( - builder: (_) => Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Checkbox( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Observer( + builder: (_) => Checkbox( // Чекбокс для капитанов value: selectTeam.capitan, checkColor: Colors.blue, activeColor: Colors.white, onChanged: selectTeam.changeCapitan, ), - Text( - 'Я капитан команды', - style: TextStyle( - color: Colors.white, - ), + ), + Text( + 'Я капитан команды', + style: TextStyle( + color: Colors.white, ), - ], - ), - Container( + ), + ], + ), + Observer( + builder: (_) => Container( child: Column( children: [ Padding( @@ -65,19 +61,27 @@ class SelectTeamView extends StatelessWidget { ), ), selectTeam.capitan - ? TextField( - // Ввод названия команды для капитана - decoration: InputDecoration( - fillColor: Colors.white, filled: true), - onChanged: selectTeam.changeTeam, - controller: TextEditingController.fromValue( - TextEditingValue( - text: selectTeam.lastTeamName, - selection: TextSelection.collapsed( - offset: selectTeam.lastTeamName.length), + ? ListTile( + leading: SizedBox(), + title: Observer( + builder: (_) => TextField( + // Ввод названия команды для капитана + decoration: InputDecoration( + fillColor: Colors.white, filled: true), + onChanged: selectTeam.changeTeam, + controller: TextEditingController.fromValue( + TextEditingValue( + text: selectTeam.lastTeamName, + selection: TextSelection.collapsed( + offset: selectTeam.lastTeamName.length), + ), + ), + textAlign: TextAlign.center, ), ), - textAlign: TextAlign.center, + trailing: Observer( + builder: (_) => selectTeam.enableIcon, + ), ) : Text('Список команд'), ], @@ -135,8 +139,8 @@ class SelectTeamView extends StatelessWidget { // ], // ), ), - ], - ), + ), + ], ), ), Observer( @@ -145,8 +149,14 @@ class SelectTeamView extends StatelessWidget { style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.green), ), - onPressed: selectTeam.capitan ? () {} : null, - child: Text(selectTeam.capitan ? 'Зарегистрировать команду' : ''), + onPressed: selectTeam.capitan ? + selectTeam.registrateTeam // отправить на сервер новую команду + : null, + child: Observer( + builder: (_) => Text(selectTeam.capitan && selectTeam.enableName + ? 'Зарегистрировать команду' + : ''), + ), ), ), ], diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/data/player.dart new file mode 100644 index 0000000..43aba0a --- /dev/null +++ b/team_c_f/lib/data/player.dart @@ -0,0 +1,16 @@ +class Player { + late String docId; + final String uid; + final String name; + late List points = []; + + Player({required this.uid, required this.name}); + + Map toMap() { + return { + 'UserId': uid, + 'Name': name, + 'Points': points, + }; + } +} diff --git a/team_c_f/lib/data/singledata/login.dart b/team_c_f/lib/data/singledata/login.dart deleted file mode 100644 index 8dd863a..0000000 --- a/team_c_f/lib/data/singledata/login.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:team_c_f/store/login/login.dart'; - -class DataLogin extends ChangeNotifier{ - Login? login; - - DataLogin() - { - login = Login(); - } -} \ No newline at end of file diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/data/team.dart new file mode 100644 index 0000000..8a54a4d --- /dev/null +++ b/team_c_f/lib/data/team.dart @@ -0,0 +1,18 @@ +class Team { + late String docId; + final String name; + final String uidCapitan; + List players = []; + + Team({required this.name, required this.uidCapitan}) { + players.add(this.uidCapitan); + } + + Map toMap() { + return { + 'Name': name, + 'Capitan': uidCapitan, + 'Players': players, + }; + } +} diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart index e9c3c5f..33f10c5 100644 --- a/team_c_f/lib/main.dart +++ b/team_c_f/lib/main.dart @@ -1,10 +1,7 @@ import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:onesignal_flutter/onesignal_flutter.dart'; -import 'package:provider/provider.dart'; -import 'package:team_c_f/components/login.dart'; -import 'package:team_c_f/data/singledata/login.dart'; -import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/pages/login.dart'; Future main() async { myApp(); @@ -18,21 +15,3 @@ myApp() async { runApp(LoginPage()); } - -class LoginPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - home: MultiProvider( - providers: [ - Provider(create: (_) => Login()), - ], - child: SafeArea( - child: Scaffold( - body: LoginView(), - ), - ), - ), - ); - } -} diff --git a/team_c_f/lib/pages/login.dart b/team_c_f/lib/pages/login.dart index 1a4b198..26cf045 100644 --- a/team_c_f/lib/pages/login.dart +++ b/team_c_f/lib/pages/login.dart @@ -1,97 +1,22 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/old/data/data.dart'; -import 'package:team_c_f/old/element/selectTeam.dart'; - -class Sign extends StatefulWidget { - // Класс отображения страницы входа в Google-аккаунт и регистрации в приложении - Sign({Key? key}) : super(key: key); - - @override - _SignState createState() => _SignState(); -} - -class _SignState extends State { - TextEditingController nameController = - TextEditingController(); // Контроллер для ввода имени участника +import 'package:team_c_f/components/login.dart'; +import 'package:team_c_f/store/login/login.dart'; +class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - body: Container( - height: double.infinity, - width: double.infinity, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () { - context - .read() - .changeSignIn(); // Изменение состояния входа в Google-аккаунт - }, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(context.watch().signIn ? 'Выйти' : 'Войти'), - SizedBox(width: 10), - Image( - image: AssetImage('assets/images/google.png'), - fit: BoxFit.fill, - height: 30, - ), - ], - ), - ), - Text( - context.watch().signIn - ? 'Вход выполнен, осталось совсем чуть чуть' - : 'Необходимо войти в аккаунт', - textAlign: TextAlign.center, - ), - SizedBox( - height: 20, - ), - Container( - padding: const EdgeInsets.all(8.0), - margin: const EdgeInsets.all(8.0), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(16.0), - ), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - 'Введите ваше имя и фамилию', - style: TextStyle( - color: Colors.white, - ), - ), - ), - TextField( - decoration: - InputDecoration(fillColor: Colors.white, filled: true), - // Ввод имени участника - controller: nameController, - onChanged: (str) { - setState(() {}); - }, - textAlign: TextAlign.center, - ), - ], - ), - ), - SelectTeam( - message: 'Зарегистрироваться', - name: nameController.text.trim(), - ), - SizedBox(height: 100,), - ], + return MaterialApp( + home: MultiProvider( + providers: [ + Provider(create: (_) => Login()), + ], + child: SafeArea( + child: Scaffold( + body: LoginView(), + ), ), ), ); } -} +} \ No newline at end of file diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart index c73a1fd..e69de29 100644 --- a/team_c_f/lib/servises/login.dart +++ b/team_c_f/lib/servises/login.dart @@ -1,16 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -class LoginService { - final CollectionReference playersCollection = - FirebaseFirestore.instance.collection('players'); - final CollectionReference teamsCollection = - FirebaseFirestore.instance.collection('teams'); - - Future checkTeamName({required String name}) { - // Проверка названия команды на уникальность - return teamsCollection - .where('Title', isEqualTo: name) - .get() - .then((response) => response.docs.length == 0); - } -} diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart new file mode 100644 index 0000000..00e7768 --- /dev/null +++ b/team_c_f/lib/servises/selectteam.dart @@ -0,0 +1,37 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/data/player.dart'; + +class SelectTeamService { + final CollectionReference _playersCollection = + FirebaseFirestore.instance.collection('players'); + final CollectionReference _teamsCollection = + FirebaseFirestore.instance.collection('teams'); + + Future checkTeamName({required String name}) { + // Проверка названия команды на уникальность + return _teamsCollection + .where('Name2', isEqualTo: name) + .get() + .then((response) => response.docs.length == 0); + } + + void registrateTeam({required Team team}){ + // регистрация команды + _teamsCollection.add(team.toMap()); + } + + // Future existPlayer({required String uid}){ + // _playersCollection.where(field) + // } + + void registratePlayer({required Player player}){ + // регистрация игрока + _playersCollection.add(player.toMap()); + } + + void updatePlayer({required Player player}){ + + // обновление игрока (добавление команды) + } +} \ No newline at end of file diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index 699c4bc..e90f56b 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -14,10 +14,8 @@ abstract class LoginBase with Store { LoginBase() { googleLogin(); } - - @observable - bool login = false; - + String uid = ''; + @observable String userName = 'No user'; @@ -56,8 +54,10 @@ abstract class LoginBase with Store { if (user?.uid != null) { loginStatus = ObservableFuture.value(true); + uid = user!.uid; } else { loginStatus = ObservableFuture.value(false); + uid = ''; } return Future.value(true); } @@ -67,6 +67,7 @@ abstract class LoginBase with Store { _googleSignIn.signOut(); _auth.signOut(); loginStatus = ObservableFuture.value(false); + uid = ''; return await Future.value(true); } diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart index b794888..66aa1af 100644 --- a/team_c_f/lib/store/login/login.g.dart +++ b/team_c_f/lib/store/login/login.g.dart @@ -17,21 +17,6 @@ mixin _$Login on LoginBase, Store { name: 'LoginBase.updatedLoginStatus')) .value; - final _$loginAtom = Atom(name: 'LoginBase.login'); - - @override - bool get login { - _$loginAtom.reportRead(); - return super.login; - } - - @override - set login(bool value) { - _$loginAtom.reportWrite(value, super.login, () { - super.login = value; - }); - } - final _$userNameAtom = Atom(name: 'LoginBase.userName'); @override @@ -103,7 +88,6 @@ mixin _$Login on LoginBase, Store { @override String toString() { return ''' -login: ${login}, userName: ${userName}, loginStatus: ${loginStatus}, updatedLoginStatus: ${updatedLoginStatus} diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index b1f0f9e..0e20b8f 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -1,31 +1,67 @@ +import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; -import 'package:team_c_f/servises/login.dart'; +import 'package:team_c_f/servises/selectteam.dart'; +import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/data/player.dart'; part 'selectteam.g.dart'; class SelectTeam = _SelectTeamBase with _$SelectTeam; abstract class _SelectTeamBase with Store { - + //_SelectTeamBase({required this.uid, required this.userName}); + String? uid; + String? userName; + @observable String teamName = 'No team'; @action - void changeTeam(String text){ + void changeTeam(String text) { teamName = text.trim(); + SelectTeamService().checkTeamName(name: teamName).then((bool enable) { + enableIcon = Icon( + enable ? Icons.done : Icons.cancel, + color: enable ? Colors.green : Colors.red, + ); + enableName = enable; + }); } @observable - String lastTeamName = ''; + bool enableName = false; - @computed - Future get availableTeamName async { return await LoginService().checkTeamName(name: teamName);} + @observable + String lastTeamName = ''; @observable bool capitan = false; @action - void changeCapitan(bool? value){ + void changeCapitan(bool? value) { capitan = value!; lastTeamName = teamName; } -} \ No newline at end of file + + @observable + Icon enableIcon = Icon( + Icons.done, + color: Colors.green, + ); + + @action + void registrateTeam() {// Регистрация команды + SelectTeamService().registrateTeam( + team: Team( + name: teamName, + uidCapitan: uid!, + ), + ); + //SelectTeamService(). + SelectTeamService().registratePlayer( + player: Player( + name: userName!, + uid: uid!, + ), + ); + } +} diff --git a/team_c_f/lib/store/selectteam/selectteam.g.dart b/team_c_f/lib/store/selectteam/selectteam.g.dart index 9aa9e49..e603ca9 100644 --- a/team_c_f/lib/store/selectteam/selectteam.g.dart +++ b/team_c_f/lib/store/selectteam/selectteam.g.dart @@ -9,14 +9,6 @@ part of 'selectteam.dart'; // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$SelectTeam on _SelectTeamBase, Store { - Computed>? _$availableTeamNameComputed; - - @override - Future get availableTeamName => (_$availableTeamNameComputed ??= - Computed>(() => super.availableTeamName, - name: '_SelectTeamBase.availableTeamName')) - .value; - final _$teamNameAtom = Atom(name: '_SelectTeamBase.teamName'); @override @@ -32,6 +24,21 @@ mixin _$SelectTeam on _SelectTeamBase, Store { }); } + final _$enableNameAtom = Atom(name: '_SelectTeamBase.enableName'); + + @override + bool get enableName { + _$enableNameAtom.reportRead(); + return super.enableName; + } + + @override + set enableName(bool value) { + _$enableNameAtom.reportWrite(value, super.enableName, () { + super.enableName = value; + }); + } + final _$lastTeamNameAtom = Atom(name: '_SelectTeamBase.lastTeamName'); @override @@ -62,6 +69,21 @@ mixin _$SelectTeam on _SelectTeamBase, Store { }); } + final _$enableIconAtom = Atom(name: '_SelectTeamBase.enableIcon'); + + @override + Icon get enableIcon { + _$enableIconAtom.reportRead(); + return super.enableIcon; + } + + @override + set enableIcon(Icon value) { + _$enableIconAtom.reportWrite(value, super.enableIcon, () { + super.enableIcon = value; + }); + } + final _$_SelectTeamBaseActionController = ActionController(name: '_SelectTeamBase'); @@ -87,13 +109,25 @@ mixin _$SelectTeam on _SelectTeamBase, Store { } } + @override + void registrateTeam() { + final _$actionInfo = _$_SelectTeamBaseActionController.startAction( + name: '_SelectTeamBase.registrateTeam'); + try { + return super.registrateTeam(); + } finally { + _$_SelectTeamBaseActionController.endAction(_$actionInfo); + } + } + @override String toString() { return ''' teamName: ${teamName}, +enableName: ${enableName}, lastTeamName: ${lastTeamName}, capitan: ${capitan}, -availableTeamName: ${availableTeamName} +enableIcon: ${enableIcon} '''; } } From 396586a9055fe2220eb126e7d7d2e61f0f1e4d70 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 26 Apr 2021 23:39:20 +0300 Subject: [PATCH 06/24] =?UTF-8?q?=D0=A0=D0=B5=D0=B3=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=20=D0=BE=D0=B1=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=83=D1=87=D0=B0?= =?UTF-8?q?=D1=82=D1=81=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/selectteam.dart | 3 +-- team_c_f/lib/data/player.dart | 4 +-- team_c_f/lib/servises/selectteam.dart | 23 ++++++++++------- team_c_f/lib/store/selectteam/selectteam.dart | 25 +++++++++++++------ 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index f41de17..9ea6c20 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:provider/provider.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; class SelectTeamView extends StatelessWidget { @@ -149,7 +148,7 @@ class SelectTeamView extends StatelessWidget { style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.green), ), - onPressed: selectTeam.capitan ? + onPressed: selectTeam.capitan && selectTeam.enableName ? selectTeam.registrateTeam // отправить на сервер новую команду : null, child: Observer( diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/data/player.dart index 43aba0a..2e8082b 100644 --- a/team_c_f/lib/data/player.dart +++ b/team_c_f/lib/data/player.dart @@ -1,10 +1,10 @@ class Player { - late String docId; + String? docId; final String uid; final String name; late List points = []; - Player({required this.uid, required this.name}); + Player({required this.uid, required this.name, this.docId}); Map toMap() { return { diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart index 00e7768..056d1df 100644 --- a/team_c_f/lib/servises/selectteam.dart +++ b/team_c_f/lib/servises/selectteam.dart @@ -11,27 +11,32 @@ class SelectTeamService { Future checkTeamName({required String name}) { // Проверка названия команды на уникальность return _teamsCollection - .where('Name2', isEqualTo: name) + .where('Name', isEqualTo: name) .get() .then((response) => response.docs.length == 0); } - void registrateTeam({required Team team}){ + void registrateTeam({required Team team}) { // регистрация команды _teamsCollection.add(team.toMap()); } - // Future existPlayer({required String uid}){ - // _playersCollection.where(field) - // } + Future existPlayer({required String uid}) { + return _playersCollection + .where( + 'UserId', + isEqualTo: uid, + ) + .get() + .then((QuerySnapshot response) => response.docs.isNotEmpty ? response.docs.single.id : null); + } - void registratePlayer({required Player player}){ + void registratePlayer({required Player player}) { // регистрация игрока _playersCollection.add(player.toMap()); } - void updatePlayer({required Player player}){ - + void updatePlayer({required Player player}) { // обновление игрока (добавление команды) } -} \ No newline at end of file +} diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index 0e20b8f..c165b95 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -8,7 +8,6 @@ part 'selectteam.g.dart'; class SelectTeam = _SelectTeamBase with _$SelectTeam; abstract class _SelectTeamBase with Store { - //_SelectTeamBase({required this.uid, required this.userName}); String? uid; String? userName; @@ -49,19 +48,29 @@ abstract class _SelectTeamBase with Store { ); @action - void registrateTeam() {// Регистрация команды + void registrateTeam() { + // Регистрация команды SelectTeamService().registrateTeam( team: Team( name: teamName, uidCapitan: uid!, ), ); - //SelectTeamService(). - SelectTeamService().registratePlayer( - player: Player( - name: userName!, - uid: uid!, - ), + SelectTeamService().existPlayer(uid: uid!).then( + (String? docId) { + Player p = Player( + name: userName!, + uid: uid!, + docId: docId, + ); + docId == null + ? SelectTeamService().registratePlayer( + player: p, + ) + : SelectTeamService().updatePlayer( + player: p, + ); + }, ); } } From 9a49c58fa352fb2928be1f2bbb95f245e6f3b687 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 27 Apr 2021 14:32:52 +0300 Subject: [PATCH 07/24] =?UTF-8?q?=D0=A0=D0=B5=D0=B3=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=20=D0=B0=D0=B2=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=D1=8E=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/login.dart | 7 +- team_c_f/lib/components/selectteam.dart | 173 +++++++++--------- team_c_f/lib/data/player.dart | 4 +- team_c_f/lib/data/team.dart | 9 + team_c_f/lib/main.dart | 27 ++- team_c_f/lib/pages/home.dart | 23 +++ team_c_f/lib/pages/login.dart | 17 +- team_c_f/lib/servises/login.dart | 17 ++ team_c_f/lib/servises/selectteam.dart | 30 ++- team_c_f/lib/store/login/login.dart | 43 ++++- team_c_f/lib/store/login/login.g.dart | 34 ++++ team_c_f/lib/store/selectteam/selectteam.dart | 83 +++++---- .../lib/store/selectteam/selectteam.g.dart | 53 ++++-- 13 files changed, 363 insertions(+), 157 deletions(-) create mode 100644 team_c_f/lib/pages/home.dart diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart index 7fbd9de..dd402f5 100644 --- a/team_c_f/lib/components/login.dart +++ b/team_c_f/lib/components/login.dart @@ -3,7 +3,6 @@ import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/components/selectteam.dart'; import 'package:team_c_f/store/login/login.dart'; -import 'package:team_c_f/store/selectteam/selectteam.dart'; class LoginView extends StatelessWidget { @override @@ -82,11 +81,9 @@ class LoginView extends StatelessWidget { ), Observer( builder: (_) { - SelectTeam selectTeam = Provider.of(context).selectTeam; - selectTeam.userName = Provider.of(context).userName; - selectTeam.uid = Provider.of(context).uid; + Provider.of(context).setDataToSelectTeam(buttonText: 'Зарегистрироваться'); return SelectTeamView( - selectTeam: selectTeam, + selectTeam: Provider.of(context).selectTeam, ); }, ), diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index 9ea6c20..2743169 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; class SelectTeamView extends StatelessWidget { @@ -12,7 +14,7 @@ class SelectTeamView extends StatelessWidget { }) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context) { return Column( children: [ Container( @@ -46,23 +48,21 @@ class SelectTeamView extends StatelessWidget { ), Observer( builder: (_) => Container( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - selectTeam.capitan - ? 'Введите название вашей команды' - : 'Выбери команду', - style: TextStyle( - color: Colors.white, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + selectTeam.capitan + ? 'Введите название вашей команды' + : 'Выбери команду', + style: TextStyle( + color: Colors.white, + ), ), ), - ), - selectTeam.capitan - ? ListTile( - leading: SizedBox(), - title: Observer( + selectTeam.capitan + ? Observer( builder: (_) => TextField( // Ввод названия команды для капитана decoration: InputDecoration( @@ -77,67 +77,46 @@ class SelectTeamView extends StatelessWidget { ), textAlign: TextAlign.center, ), + ) + : Observer( + builder: (_) => selectTeam.allTeamNames.isNotEmpty + ? DropdownButton( + value: selectTeam.selectedTeam, + onChanged: selectTeam.selestTeam, + items: [ + ...selectTeam.allTeamNames + .map>( + (String team) => DropdownMenuItem( + child: Text(team), + value: team, + ), + ) + .toList(), + ], + ) + : Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text( + 'Ни одной доступной команды нет', + style: TextStyle( + color: Colors.white, + ), + ), + Text( + 'Можешь создать команду сам \u261d', + style: TextStyle( + color: Colors.white, + ), + ) + ], + ), + ), ), - trailing: Observer( - builder: (_) => selectTeam.enableIcon, - ), - ) - : Text('Список команд'), - ], - ) - // : LoginService().checkTeamName(name: login.teamName) // Проверка существуют ли команды, чтобы в них зарегистрироваться - // ? Column( - // // Для пустого списка - // children: [ - // Text( - // 'Ни одной доступной команды нет', - // style: TextStyle( - // color: Colors.white, - // ), - // ), - // Text( - // 'Можешь создать команду сам \u261d', - // style: TextStyle( - // color: Colors.white, - // ), - // ) - // ], - // ) - // : Column( - // // Для непустого списка - // children: [ - // Observer( - // builder: (_) => Text( - // login.userName, - // //'Выбери свою команду', - // style: TextStyle( - // color: Colors.white, - // ), - // ), - // ), - // // DropdownButton( - // // value: teamSelect, - // // onChanged: (newName) { - // // setState(() { - // // teamSelect = newName; - // // }); - // // }, - // // items: [ - // // ...context - // // .watch() - // // .allTeamNames - // // .map>( - // // (String team) => DropdownMenuItem( - // // child: Text(team), - // // value: team, - // // ), - // // ) - // // .toList(), - // // ], - // // ), - // ], - // ), - ), + ], + ), + ), ), ], ), @@ -148,13 +127,43 @@ class SelectTeamView extends StatelessWidget { style: ButtonStyle( backgroundColor: MaterialStateProperty.all(Colors.green), ), - onPressed: selectTeam.capitan && selectTeam.enableName ? - selectTeam.registrateTeam // отправить на сервер новую команду - : null, + onPressed: selectTeam.uName.isNotEmpty + ? selectTeam.capitan + ? selectTeam.teamName.isNotEmpty + ? selectTeam.enableName + ? () { + selectTeam.registrateTeam().then( + (_) { + context.read().validateInApp(); + context.read().clearData(); + }, + ); + } + : null + : null + : selectTeam.selectedTeam != null + ? () { + selectTeam.assertTeam().then( + (_) { + context.read().validateInApp(); + context.read().clearData(); + }, + ); + } + : null + : null, child: Observer( - builder: (_) => Text(selectTeam.capitan && selectTeam.enableName - ? 'Зарегистрировать команду' - : ''), + builder: (_) => Text(selectTeam.uName.isNotEmpty + ? selectTeam.capitan + ? selectTeam.teamName.isNotEmpty + ? selectTeam.enableName + ? 'Зарегистрировать команду' + : 'Данное название команды недоступно' + : 'Введите название команды' + : selectTeam.selectedTeam != null + ? selectTeam.regButtonText + : 'Выберите команду' + : 'Введите имя и фамилию'), ), ), ), diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/data/player.dart index 2e8082b..106a29a 100644 --- a/team_c_f/lib/data/player.dart +++ b/team_c_f/lib/data/player.dart @@ -2,14 +2,16 @@ class Player { String? docId; final String uid; final String name; + final String? team; late List points = []; - Player({required this.uid, required this.name, this.docId}); + Player({required this.uid, required this.name, required this.team, this.docId}); Map toMap() { return { 'UserId': uid, 'Name': name, + 'Team': team, 'Points': points, }; } diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/data/team.dart index 8a54a4d..a977c9a 100644 --- a/team_c_f/lib/data/team.dart +++ b/team_c_f/lib/data/team.dart @@ -15,4 +15,13 @@ class Team { 'Players': players, }; } + + factory Team.fromMap(Map map) { + Team t = Team( + name: map['Name'] as String, + uidCapitan: map['Capitan'], + ); + t.players = [...map['Players']]; + return t; + } } diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart index 33f10c5..9f335e5 100644 --- a/team_c_f/lib/main.dart +++ b/team_c_f/lib/main.dart @@ -1,7 +1,11 @@ import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:onesignal_flutter/onesignal_flutter.dart'; +import 'package:provider/provider.dart'; import 'package:team_c_f/pages/login.dart'; +import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/pages/home.dart'; Future main() async { myApp(); @@ -13,5 +17,26 @@ myApp() async { OneSignal.shared.setAppId('93b27d54-e442-4af5-86e4-a215faf20e3a'); - runApp(LoginPage()); + runApp( + MaterialApp( + home: MultiProvider( + providers: [ + Provider(create: (_) => Login()), + ], + child: FirstPage(), + ), + ), + ); +} + +class FirstPage extends StatelessWidget { + const FirstPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Observer( + builder: (_) => Provider.of(context).registrateInApp + ? HomePage() + : LoginPage()); + } } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart new file mode 100644 index 0000000..d96662a --- /dev/null +++ b/team_c_f/lib/pages/home.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/store/login/login.dart'; + +class HomePage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + body: Column( + children: [ + Text('Домашний экран'), + ElevatedButton( + onPressed: Provider.of(context).googleLogout, + child: Text( + 'logout', + )), + ], + ), + ), + ); + } +} diff --git a/team_c_f/lib/pages/login.dart b/team_c_f/lib/pages/login.dart index 26cf045..32184f2 100644 --- a/team_c_f/lib/pages/login.dart +++ b/team_c_f/lib/pages/login.dart @@ -1,22 +1,13 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:team_c_f/components/login.dart'; -import 'package:team_c_f/store/login/login.dart'; class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { - return MaterialApp( - home: MultiProvider( - providers: [ - Provider(create: (_) => Login()), - ], - child: SafeArea( - child: Scaffold( - body: LoginView(), - ), - ), + return SafeArea( + child: Scaffold( + body: LoginView(), ), ); } -} \ No newline at end of file +} diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart index e69de29..c2f5704 100644 --- a/team_c_f/lib/servises/login.dart +++ b/team_c_f/lib/servises/login.dart @@ -0,0 +1,17 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +class LoginService { + final CollectionReference _playersCollection = + FirebaseFirestore.instance.collection('players'); + + Future existPlayer({required String uid}) { + return _playersCollection + .where( + 'UserId', + isEqualTo: uid, + ) + .get() + .then((QuerySnapshot response) => + response.docs.isNotEmpty); + } +} diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart index 056d1df..0f8d595 100644 --- a/team_c_f/lib/servises/selectteam.dart +++ b/team_c_f/lib/servises/selectteam.dart @@ -16,9 +16,9 @@ class SelectTeamService { .then((response) => response.docs.length == 0); } - void registrateTeam({required Team team}) { + Future registrateTeam({required Team team}) async { // регистрация команды - _teamsCollection.add(team.toMap()); + await _teamsCollection.add(team.toMap()); } Future existPlayer({required String uid}) { @@ -28,15 +28,33 @@ class SelectTeamService { isEqualTo: uid, ) .get() - .then((QuerySnapshot response) => response.docs.isNotEmpty ? response.docs.single.id : null); + .then((QuerySnapshot response) => + response.docs.isNotEmpty ? response.docs.single.id : null); } - void registratePlayer({required Player player}) { + Future?> allTeamNames() { + return _teamsCollection.get().then( + (QuerySnapshot response) => response.docs + .where((QueryDocumentSnapshot doc) => + Team.fromMap(doc.data()).players.length < 3) + .map( + (QueryDocumentSnapshot doc) => Team.fromMap(doc.data()).name, + ) + .toList(), + ); + } + + Future registratePlayer({required Player player}) async { // регистрация игрока - _playersCollection.add(player.toMap()); + await _playersCollection.add(player.toMap()); + return true; } - void updatePlayer({required Player player}) { + Future updatePlayer({required Player player}) async { // обновление игрока (добавление команды) + await _playersCollection.doc(player.docId).update( + player.toMap(), + ); + return true; } } diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index e90f56b..e7b9cc5 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -1,6 +1,7 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:mobx/mobx.dart'; +import 'package:team_c_f/servises/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; part 'login.g.dart'; @@ -14,10 +15,10 @@ abstract class LoginBase with Store { LoginBase() { googleLogin(); } - String uid = ''; - + String userId = ''; + @observable - String userName = 'No user'; + String userName = ''; @action void changeName(String text) { @@ -26,6 +27,9 @@ abstract class LoginBase with Store { final selectTeam = SelectTeam(); + @observable + bool registrateInApp = false; + @observable ObservableFuture loginStatus = ObservableFuture.value(false); @@ -52,12 +56,14 @@ abstract class LoginBase with Store { user = userCredential.user; - if (user?.uid != null) { + if (user != null) { loginStatus = ObservableFuture.value(true); - uid = user!.uid; + userId = user.uid; + validateInApp(); } else { loginStatus = ObservableFuture.value(false); - uid = ''; + userId = ''; + registrateInApp = false; } return Future.value(true); } @@ -67,10 +73,16 @@ abstract class LoginBase with Store { _googleSignIn.signOut(); _auth.signOut(); loginStatus = ObservableFuture.value(false); - uid = ''; + userId = ''; + registrateInApp = false; return await Future.value(true); } + @action + Future validateInApp() async { + registrateInApp = await LoginService().existPlayer(uid: userId); + } + Future getGoogleUser() async { GoogleSignInAccount? googleUser = _googleSignIn.currentUser; if (googleUser == null) { @@ -81,4 +93,21 @@ abstract class LoginBase with Store { } return googleUser; } + + @action + void clearData(){ + userName = ''; + selectTeam.lastTeamName = ''; + selectTeam.teamName = ''; + selectTeam.uName = ''; + selectTeam.selectedTeam = null; + } + + void setDataToSelectTeam({ + required String buttonText, + }) { + selectTeam.uId = userId; + selectTeam.uName = userName; + selectTeam.regButtonText = buttonText; + } } diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart index 66aa1af..b6f441c 100644 --- a/team_c_f/lib/store/login/login.g.dart +++ b/team_c_f/lib/store/login/login.g.dart @@ -32,6 +32,21 @@ mixin _$Login on LoginBase, Store { }); } + final _$registrateInAppAtom = Atom(name: 'LoginBase.registrateInApp'); + + @override + bool get registrateInApp { + _$registrateInAppAtom.reportRead(); + return super.registrateInApp; + } + + @override + set registrateInApp(bool value) { + _$registrateInAppAtom.reportWrite(value, super.registrateInApp, () { + super.registrateInApp = value; + }); + } + final _$loginStatusAtom = Atom(name: 'LoginBase.loginStatus'); @override @@ -61,6 +76,13 @@ mixin _$Login on LoginBase, Store { return _$googleLogoutAsyncAction.run(() => super.googleLogout()); } + final _$validateInAppAsyncAction = AsyncAction('LoginBase.validateInApp'); + + @override + Future validateInApp() { + return _$validateInAppAsyncAction.run(() => super.validateInApp()); + } + final _$LoginBaseActionController = ActionController(name: 'LoginBase'); @override @@ -85,10 +107,22 @@ mixin _$Login on LoginBase, Store { } } + @override + void clearData() { + final _$actionInfo = + _$LoginBaseActionController.startAction(name: 'LoginBase.clearData'); + try { + return super.clearData(); + } finally { + _$LoginBaseActionController.endAction(_$actionInfo); + } + } + @override String toString() { return ''' userName: ${userName}, +registrateInApp: ${registrateInApp}, loginStatus: ${loginStatus}, updatedLoginStatus: ${updatedLoginStatus} '''; diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index c165b95..822224d 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; import 'package:team_c_f/servises/selectteam.dart'; import 'package:team_c_f/data/team.dart'; @@ -8,22 +7,26 @@ part 'selectteam.g.dart'; class SelectTeam = _SelectTeamBase with _$SelectTeam; abstract class _SelectTeamBase with Store { - String? uid; - String? userName; + _SelectTeamBase() { + getAllTeamNames().then( + (List? allNames) => + allTeamNames = allNames == null ? [] : [...allNames], + ); + } + String regButtonText = 'Зарегистрироваться'; + String? uId; + String uName = ''; @observable - String teamName = 'No team'; + String teamName = ''; @action void changeTeam(String text) { teamName = text.trim(); SelectTeamService().checkTeamName(name: teamName).then((bool enable) { - enableIcon = Icon( - enable ? Icons.done : Icons.cancel, - color: enable ? Colors.green : Colors.red, - ); enableName = enable; }); + editNameComplite(text: text); } @observable @@ -32,6 +35,10 @@ abstract class _SelectTeamBase with Store { @observable String lastTeamName = ''; + void editNameComplite({required String text}) { + lastTeamName = text; + } + @observable bool capitan = false; @@ -42,35 +49,49 @@ abstract class _SelectTeamBase with Store { } @observable - Icon enableIcon = Icon( - Icons.done, - color: Colors.green, - ); + String? selectedTeam; + + @action + void selestTeam(String? name) { + selectedTeam = name; + } + + @observable + List allTeamNames = []; @action - void registrateTeam() { + Future assertTeam() async { + // Выбор команды + String? docId = await SelectTeamService().existPlayer(uid: uId!); + + Player p = Player( + team: capitan ? teamName : selectedTeam, + name: uName, + uid: uId!, + docId: docId, + ); + return docId == null + ? await SelectTeamService().registratePlayer( + player: p, + ) + : await SelectTeamService().updatePlayer( + player: p, + ); + } + + @action + Future registrateTeam() async { // Регистрация команды - SelectTeamService().registrateTeam( + await SelectTeamService().registrateTeam( team: Team( name: teamName, - uidCapitan: uid!, + uidCapitan: uId!, ), ); - SelectTeamService().existPlayer(uid: uid!).then( - (String? docId) { - Player p = Player( - name: userName!, - uid: uid!, - docId: docId, - ); - docId == null - ? SelectTeamService().registratePlayer( - player: p, - ) - : SelectTeamService().updatePlayer( - player: p, - ); - }, - ); + await assertTeam(); + } + + Future?> getAllTeamNames() { + return SelectTeamService().allTeamNames(); } } diff --git a/team_c_f/lib/store/selectteam/selectteam.g.dart b/team_c_f/lib/store/selectteam/selectteam.g.dart index e603ca9..cb6729b 100644 --- a/team_c_f/lib/store/selectteam/selectteam.g.dart +++ b/team_c_f/lib/store/selectteam/selectteam.g.dart @@ -69,21 +69,51 @@ mixin _$SelectTeam on _SelectTeamBase, Store { }); } - final _$enableIconAtom = Atom(name: '_SelectTeamBase.enableIcon'); + final _$selectedTeamAtom = Atom(name: '_SelectTeamBase.selectedTeam'); @override - Icon get enableIcon { - _$enableIconAtom.reportRead(); - return super.enableIcon; + String? get selectedTeam { + _$selectedTeamAtom.reportRead(); + return super.selectedTeam; } @override - set enableIcon(Icon value) { - _$enableIconAtom.reportWrite(value, super.enableIcon, () { - super.enableIcon = value; + set selectedTeam(String? value) { + _$selectedTeamAtom.reportWrite(value, super.selectedTeam, () { + super.selectedTeam = value; }); } + final _$allTeamNamesAtom = Atom(name: '_SelectTeamBase.allTeamNames'); + + @override + List get allTeamNames { + _$allTeamNamesAtom.reportRead(); + return super.allTeamNames; + } + + @override + set allTeamNames(List value) { + _$allTeamNamesAtom.reportWrite(value, super.allTeamNames, () { + super.allTeamNames = value; + }); + } + + final _$assertTeamAsyncAction = AsyncAction('_SelectTeamBase.assertTeam'); + + @override + Future assertTeam() { + return _$assertTeamAsyncAction.run(() => super.assertTeam()); + } + + final _$registrateTeamAsyncAction = + AsyncAction('_SelectTeamBase.registrateTeam'); + + @override + Future registrateTeam() { + return _$registrateTeamAsyncAction.run(() => super.registrateTeam()); + } + final _$_SelectTeamBaseActionController = ActionController(name: '_SelectTeamBase'); @@ -110,11 +140,11 @@ mixin _$SelectTeam on _SelectTeamBase, Store { } @override - void registrateTeam() { + void selestTeam(String? name) { final _$actionInfo = _$_SelectTeamBaseActionController.startAction( - name: '_SelectTeamBase.registrateTeam'); + name: '_SelectTeamBase.selestTeam'); try { - return super.registrateTeam(); + return super.selestTeam(name); } finally { _$_SelectTeamBaseActionController.endAction(_$actionInfo); } @@ -127,7 +157,8 @@ teamName: ${teamName}, enableName: ${enableName}, lastTeamName: ${lastTeamName}, capitan: ${capitan}, -enableIcon: ${enableIcon} +selectedTeam: ${selectedTeam}, +allTeamNames: ${allTeamNames} '''; } } From 410d9fddac804845a7e3aed7305ae50bd8767380 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 28 Apr 2021 14:26:48 +0300 Subject: [PATCH 08/24] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/login.dart | 17 ++++- team_c_f/lib/components/reglament.dart | 49 +++++++++++++ team_c_f/lib/components/selectteam.dart | 24 ++++--- team_c_f/lib/data/currenttour.dart | 14 ++++ team_c_f/lib/data/data.dart | 53 ++++++++++++++ team_c_f/lib/data/info.dart | 22 ++++++ team_c_f/lib/data/player.dart | 20 +++++- team_c_f/lib/data/team.dart | 17 +++-- team_c_f/lib/data/tour.dart | 18 +++++ team_c_f/lib/pages/home.dart | 9 ++- team_c_f/lib/servises/data.dart | 69 +++++++++++++++++++ team_c_f/lib/servises/login.dart | 14 +++- team_c_f/lib/servises/selectteam.dart | 4 +- team_c_f/lib/store/login/login.dart | 10 +++ team_c_f/lib/store/selectteam/selectteam.dart | 8 +-- 15 files changed, 320 insertions(+), 28 deletions(-) create mode 100644 team_c_f/lib/components/reglament.dart create mode 100644 team_c_f/lib/data/currenttour.dart create mode 100644 team_c_f/lib/data/data.dart create mode 100644 team_c_f/lib/data/info.dart create mode 100644 team_c_f/lib/data/tour.dart create mode 100644 team_c_f/lib/servises/data.dart diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart index dd402f5..8f4e8e6 100644 --- a/team_c_f/lib/components/login.dart +++ b/team_c_f/lib/components/login.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/components/reglament.dart'; import 'package:team_c_f/components/selectteam.dart'; import 'package:team_c_f/store/login/login.dart'; @@ -46,8 +47,17 @@ class LoginView extends StatelessWidget { textAlign: TextAlign.center, ), ), - SizedBox( - height: 20, + Observer( + builder: (_) => TextButton( + onPressed: () { + if (login.info != null) + Navigator.of(context) + .push(MaterialPageRoute( + builder: (_) => Reglament(info: login.info!))) + .then((value) => login.changeName(value!.toString())); + }, + child: Text('Правила конкурса'), + ), ), Container( padding: const EdgeInsets.all(8.0), @@ -81,7 +91,8 @@ class LoginView extends StatelessWidget { ), Observer( builder: (_) { - Provider.of(context).setDataToSelectTeam(buttonText: 'Зарегистрироваться'); + Provider.of(context) + .setDataToSelectTeam(buttonText: 'Зарегистрироваться'); return SelectTeamView( selectTeam: Provider.of(context).selectTeam, ); diff --git a/team_c_f/lib/components/reglament.dart b/team_c_f/lib/components/reglament.dart new file mode 100644 index 0000000..3b06e25 --- /dev/null +++ b/team_c_f/lib/components/reglament.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/data/info.dart'; + +class Reglament extends StatelessWidget { + final Info info; + Reglament({required this.info}); + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: Row( + children: [ + InkWell( + child: Icon(Icons.arrow_back, size: 30), + onTap: () { + Navigator.of(context).pop(true); + }, + ), + // IconButton( + // icon: Icon(Icons.arrow_back), + // onPressed: () { + // Navigator.of(context).pop(); + // }, + // ), + SizedBox(width: 20), + Text('Правила конкурса'), + ], + ), + ), + body: Container( + height: double.infinity, + width: double.infinity, + child: ListView( + padding: const EdgeInsets.all(8.0), + children: [ + ...info.regulations.map( + (String item) => Padding( + padding: const EdgeInsets.all(2.0), + child: Text(item), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index 2743169..344cc1b 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -153,17 +153,19 @@ class SelectTeamView extends StatelessWidget { : null : null, child: Observer( - builder: (_) => Text(selectTeam.uName.isNotEmpty - ? selectTeam.capitan - ? selectTeam.teamName.isNotEmpty - ? selectTeam.enableName - ? 'Зарегистрировать команду' - : 'Данное название команды недоступно' - : 'Введите название команды' - : selectTeam.selectedTeam != null - ? selectTeam.regButtonText - : 'Выберите команду' - : 'Введите имя и фамилию'), + builder: (_) => Text(selectTeam.uId.isNotEmpty + ? selectTeam.uName.isNotEmpty + ? selectTeam.capitan + ? selectTeam.teamName.isNotEmpty + ? selectTeam.enableName + ? 'Зарегистрировать команду' + : 'Данное название команды недоступно' + : 'Введите название команды' + : selectTeam.selectedTeam != null + ? selectTeam.regButtonText + : 'Выберите команду' + : 'Введите имя и фамилию' + : 'Необходимо войти в Google-аккаунт'), ), ), ), diff --git a/team_c_f/lib/data/currenttour.dart b/team_c_f/lib/data/currenttour.dart new file mode 100644 index 0000000..a1c1b74 --- /dev/null +++ b/team_c_f/lib/data/currenttour.dart @@ -0,0 +1,14 @@ +class CurrentTour { + String round; + CurrentTour({required this.round}); + + Map toMap() { + return { + 'Round': round, + }; + } + + factory CurrentTour.fromMap({required Map data}){ + return CurrentTour(round: data['Round']); + } +} diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart new file mode 100644 index 0000000..41fc4d9 --- /dev/null +++ b/team_c_f/lib/data/data.dart @@ -0,0 +1,53 @@ +import 'package:team_c_f/data/currenttour.dart'; +import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/data/tour.dart'; + +class Data { + static CurrentTour? currentTour; + static List? players; + static List? teams; + static List? tours; + + // Текущий тур (подписка) + // { + // *получаемые поля + // номер тура (строка). + // } + // Игроки + // { + // *получаемые поля + // идентификатор (строка), + // имя (строка), + // название команды (строка), + // лист забитых за тур (лист интов, null при пропуске тура). + + // *вычисляемые поля + // максимум забитых за тур (инт), + // количество забитых за все матчи (инт), + // позиция (инт). + // } + // Команды + // { + // *получаемые поля + // название (строка), + // идентификатор капитана (строка) + // лист участников (лист строк с идентификаторами). + + // *вычисляемые поля + // максимум забитых за тур (инт) + // количество забитых за все матчи (инт), + // количество пропущенных за все матчи (инт), + // победы (инт), + // ничьи (инт), + // поражения (инт), + // очки (инт), + // позиция (инт). + // } + // Туры + // { + // *получаемые поля + // номер тура (строка), + // лист участников (лист типа: команда, забитые). + // } +} \ No newline at end of file diff --git a/team_c_f/lib/data/info.dart b/team_c_f/lib/data/info.dart new file mode 100644 index 0000000..12ee5cc --- /dev/null +++ b/team_c_f/lib/data/info.dart @@ -0,0 +1,22 @@ +class Info { + final List regulations; + final String link; + Info({ + required this.regulations, + required this.link, + }); + + factory Info.fromMap({required Map data}) { + return Info( + link: data['Link'], + regulations: [...data['Regulations']], + ); + } + + Map toMap(){ + return { + 'Link': link, + 'Regulations': regulations, + }; + } +} diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/data/player.dart index 106a29a..11f7c62 100644 --- a/team_c_f/lib/data/player.dart +++ b/team_c_f/lib/data/player.dart @@ -5,7 +5,15 @@ class Player { final String? team; late List points = []; - Player({required this.uid, required this.name, required this.team, this.docId}); + int? get maxTour => points.reduce((f, s) => f! < s! ? s : f); + late int goals; + late int position; + // максимум забитых за тур (инт), + // количество забитых за все матчи (инт), + // позиция (инт). + + Player( + {required this.uid, required this.name, required this.team, this.docId}); Map toMap() { return { @@ -15,4 +23,14 @@ class Player { 'Points': points, }; } + + factory Player.fromMap({required Map data}) { + Player p = Player( + name: data['Name'], + team: data['Team'], + uid: data['UserId'], + ); + p.points = [...data['Points']]; + return p; + } } diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/data/team.dart index a977c9a..2d1c24a 100644 --- a/team_c_f/lib/data/team.dart +++ b/team_c_f/lib/data/team.dart @@ -4,6 +4,15 @@ class Team { final String uidCapitan; List players = []; + late int maxTour; + late int goals; + late int missed; + late int win; + late int draw; + late int lose; + int get points => win * 3 + draw; + late int position; + Team({required this.name, required this.uidCapitan}) { players.add(this.uidCapitan); } @@ -16,12 +25,12 @@ class Team { }; } - factory Team.fromMap(Map map) { + factory Team.fromMap({required Map data}) { Team t = Team( - name: map['Name'] as String, - uidCapitan: map['Capitan'], + name: data['Name'] as String, + uidCapitan: data['Capitan'], ); - t.players = [...map['Players']]; + t.players = [...data['Players']]; return t; } } diff --git a/team_c_f/lib/data/tour.dart b/team_c_f/lib/data/tour.dart new file mode 100644 index 0000000..0c1822c --- /dev/null +++ b/team_c_f/lib/data/tour.dart @@ -0,0 +1,18 @@ +class Tour { + final String round; + late Map team; // проверить порядок + Tour({required this.round}); + + Map toMap(){ + return { + 'Round': round, + 'Team': team, + }; + } + + factory Tour.fromMap({required Map data}){ + Tour t = Tour(round: data['Round']); + t.team = data['Team']; + return t; + } +} \ No newline at end of file diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index d96662a..da02000 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -1,15 +1,22 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/servises/data.dart'; import 'package:team_c_f/store/login/login.dart'; class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { + DataService().initData(); return SafeArea( child: Scaffold( body: Column( children: [ - Text('Домашний экран'), + Data.tours != null + ? Data.tours!.isNotEmpty + ? Text(Data.tours![0].round) + : Text('Туров нет') + : Text('Идёт загрузка'), ElevatedButton( onPressed: Provider.of(context).googleLogout, child: Text( diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart new file mode 100644 index 0000000..bfacf82 --- /dev/null +++ b/team_c_f/lib/servises/data.dart @@ -0,0 +1,69 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/currenttour.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/data/tour.dart'; + +class DataService { + final CollectionReference _playersCollection = + FirebaseFirestore.instance.collection('players'); + final CollectionReference _teamsCollection = + FirebaseFirestore.instance.collection('teams'); + final CollectionReference _currentTourCollection = + FirebaseFirestore.instance.collection('currentTour'); + final CollectionReference _toursCollection = + FirebaseFirestore.instance.collection('tours'); + + void initData() { + getCurrentTour() + .then((CurrentTour currentTour) => Data.currentTour = currentTour); + getPlayers().then((List players) => Data.players = players); + getTeams().then((List teams) => Data.teams = teams); + getTours().then((List tours) => Data.tours = tours); + } + + Future getCurrentTour() { + return _currentTourCollection.get().then( + (QuerySnapshot response) => CurrentTour.fromMap( + data: response.docs.single.data(), + ), + ); + } + + Future> getPlayers() { + return _playersCollection.get().then( + (QuerySnapshot response) => response.docs + .map( + (QueryDocumentSnapshot doc) => Player.fromMap( + data: doc.data(), + ), + ) + .toList(), + ); + } + + Future> getTeams() { + return _teamsCollection.get().then( + (QuerySnapshot response) => response.docs + .map( + (QueryDocumentSnapshot doc) => Team.fromMap( + data: doc.data(), + ), + ) + .toList(), + ); + } + + Future> getTours() { + return _toursCollection.get().then( + (QuerySnapshot response) => response.docs + .map( + (QueryDocumentSnapshot doc) => Tour.fromMap( + data: doc.data(), + ), + ) + .toList(), + ); + } +} diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart index c2f5704..3060379 100644 --- a/team_c_f/lib/servises/login.dart +++ b/team_c_f/lib/servises/login.dart @@ -1,8 +1,11 @@ import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/info.dart'; class LoginService { final CollectionReference _playersCollection = FirebaseFirestore.instance.collection('players'); + final CollectionReference _infoCollection = + FirebaseFirestore.instance.collection('information'); Future existPlayer({required String uid}) { return _playersCollection @@ -11,7 +14,14 @@ class LoginService { isEqualTo: uid, ) .get() - .then((QuerySnapshot response) => - response.docs.isNotEmpty); + .then((QuerySnapshot response) => response.docs.isNotEmpty); + } + + Future getInfo() { + return _infoCollection.get().then( + (QuerySnapshot response) => Info.fromMap( + data: response.docs.single.data(), + ), + ); } } diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart index 0f8d595..5331327 100644 --- a/team_c_f/lib/servises/selectteam.dart +++ b/team_c_f/lib/servises/selectteam.dart @@ -36,9 +36,9 @@ class SelectTeamService { return _teamsCollection.get().then( (QuerySnapshot response) => response.docs .where((QueryDocumentSnapshot doc) => - Team.fromMap(doc.data()).players.length < 3) + Team.fromMap(data: doc.data()).players.length < 3) .map( - (QueryDocumentSnapshot doc) => Team.fromMap(doc.data()).name, + (QueryDocumentSnapshot doc) => Team.fromMap(data: doc.data()).name, ) .toList(), ); diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index e7b9cc5..32f7c1a 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -1,6 +1,7 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:mobx/mobx.dart'; +import 'package:team_c_f/data/info.dart'; import 'package:team_c_f/servises/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; @@ -14,7 +15,16 @@ class Login = LoginBase with _$Login; abstract class LoginBase with Store { LoginBase() { googleLogin(); + initInfo(); } + @observable + Info? info; + + @action + void initInfo(){ + LoginService().getInfo().then((Info value) => info = value); + } + String userId = ''; @observable diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index 822224d..be9b290 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -14,7 +14,7 @@ abstract class _SelectTeamBase with Store { ); } String regButtonText = 'Зарегистрироваться'; - String? uId; + String uId = ''; String uName = ''; @observable @@ -62,12 +62,12 @@ abstract class _SelectTeamBase with Store { @action Future assertTeam() async { // Выбор команды - String? docId = await SelectTeamService().existPlayer(uid: uId!); + String? docId = await SelectTeamService().existPlayer(uid: uId); Player p = Player( team: capitan ? teamName : selectedTeam, name: uName, - uid: uId!, + uid: uId, docId: docId, ); return docId == null @@ -85,7 +85,7 @@ abstract class _SelectTeamBase with Store { await SelectTeamService().registrateTeam( team: Team( name: teamName, - uidCapitan: uId!, + uidCapitan: uId, ), ); await assertTeam(); From 7337ad89e3d8f132ff2b864b2824c6bc08fd9561 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 1 May 2021 21:55:30 +0300 Subject: [PATCH 09/24] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20NavyBar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/main.dart | 2 +- team_c_f/lib/pages/home.dart | 65 +++++++++++++++++++++++++++ team_c_f/lib/store/home/home.dart | 14 ++++++ team_c_f/lib/store/home/home.g.dart | 46 +++++++++++++++++++ team_c_f/lib/store/login/login.g.dart | 27 +++++++++++ team_c_f/pubspec.lock | 7 +++ team_c_f/pubspec.yaml | 3 ++ 7 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 team_c_f/lib/store/home/home.dart create mode 100644 team_c_f/lib/store/home/home.g.dart diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart index 9f335e5..d4e1f39 100644 --- a/team_c_f/lib/main.dart +++ b/team_c_f/lib/main.dart @@ -35,7 +35,7 @@ class FirstPage extends StatelessWidget { @override Widget build(BuildContext context) { return Observer( - builder: (_) => Provider.of(context).registrateInApp + builder: (_) => context.read().registrateInApp ? HomePage() : LoginPage()); } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index da02000..80bde6c 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -1,10 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/servises/data.dart'; +import 'package:team_c_f/store/home/home.dart'; import 'package:team_c_f/store/login/login.dart'; +import 'package:bottom_navy_bar/bottom_navy_bar.dart'; class HomePage extends StatelessWidget { + static Home state = Home(); @override Widget build(BuildContext context) { DataService().initData(); @@ -24,6 +28,67 @@ class HomePage extends StatelessWidget { )), ], ), + bottomNavigationBar: Observer( + builder: (_) => BottomNavyBar( + // Бар с вариантами выбора страниц + onItemSelected: state.selectIndex, + selectedIndex: state.selectedIndex, + iconSize: 20.0, + items: [ + BottomNavyBarItem( + icon: Icon(Icons.people), + title: Column( + children: [ + Text( + 'Моя', + style: Theme.of(context).textTheme.caption, + ), + Text( + 'команда', + style: Theme.of(context).textTheme.caption, + ), + ], + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.calendar_today), + title: Text( + 'Календарь', + style: Theme.of(context).textTheme.caption, + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.add_to_photos), + title: Column( + children: [ + Text( + 'Текущий', + style: Theme.of(context).textTheme.caption, + ), + Text( + 'тур', + style: Theme.of(context).textTheme.caption, + ), + ], + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.toc), + title: Text( + 'Таблица', + style: Theme.of(context).textTheme.caption, + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.list_alt), + title: Text( + 'Бомбардиры', + style: Theme.of(context).textTheme.caption, + ), + ), + ], + ), + ), ), ); } diff --git a/team_c_f/lib/store/home/home.dart b/team_c_f/lib/store/home/home.dart new file mode 100644 index 0000000..23f3460 --- /dev/null +++ b/team_c_f/lib/store/home/home.dart @@ -0,0 +1,14 @@ +import 'package:mobx/mobx.dart'; +part 'home.g.dart'; + +class Home = _HomeBase with _$Home; + +abstract class _HomeBase with Store { + @observable + int selectedIndex = 0; + + @action + void selectIndex(int index){ + selectedIndex = index; + } +} \ No newline at end of file diff --git a/team_c_f/lib/store/home/home.g.dart b/team_c_f/lib/store/home/home.g.dart new file mode 100644 index 0000000..9958a96 --- /dev/null +++ b/team_c_f/lib/store/home/home.g.dart @@ -0,0 +1,46 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'home.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$Home on _HomeBase, Store { + final _$selectedIndexAtom = Atom(name: '_HomeBase.selectedIndex'); + + @override + int get selectedIndex { + _$selectedIndexAtom.reportRead(); + return super.selectedIndex; + } + + @override + set selectedIndex(int value) { + _$selectedIndexAtom.reportWrite(value, super.selectedIndex, () { + super.selectedIndex = value; + }); + } + + final _$_HomeBaseActionController = ActionController(name: '_HomeBase'); + + @override + void selectIndex(int index) { + final _$actionInfo = + _$_HomeBaseActionController.startAction(name: '_HomeBase.selectIndex'); + try { + return super.selectIndex(index); + } finally { + _$_HomeBaseActionController.endAction(_$actionInfo); + } + } + + @override + String toString() { + return ''' +selectedIndex: ${selectedIndex} + '''; + } +} diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart index b6f441c..af0401e 100644 --- a/team_c_f/lib/store/login/login.g.dart +++ b/team_c_f/lib/store/login/login.g.dart @@ -17,6 +17,21 @@ mixin _$Login on LoginBase, Store { name: 'LoginBase.updatedLoginStatus')) .value; + final _$infoAtom = Atom(name: 'LoginBase.info'); + + @override + Info? get info { + _$infoAtom.reportRead(); + return super.info; + } + + @override + set info(Info? value) { + _$infoAtom.reportWrite(value, super.info, () { + super.info = value; + }); + } + final _$userNameAtom = Atom(name: 'LoginBase.userName'); @override @@ -85,6 +100,17 @@ mixin _$Login on LoginBase, Store { final _$LoginBaseActionController = ActionController(name: 'LoginBase'); + @override + void initInfo() { + final _$actionInfo = + _$LoginBaseActionController.startAction(name: 'LoginBase.initInfo'); + try { + return super.initInfo(); + } finally { + _$LoginBaseActionController.endAction(_$actionInfo); + } + } + @override void changeName(String text) { final _$actionInfo = @@ -121,6 +147,7 @@ mixin _$Login on LoginBase, Store { @override String toString() { return ''' +info: ${info}, userName: ${userName}, registrateInApp: ${registrateInApp}, loginStatus: ${loginStatus}, diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index bb84dc6..db89276 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -50,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + bottom_navy_bar: + dependency: "direct main" + description: + name: bottom_navy_bar + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.0" build: dependency: transitive description: diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index da9ad43..1c4e309 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -32,7 +32,10 @@ dependencies: http: ^0.13.1 html: ^0.15.0 carousel_slider: ^3.0.0 + custom_navigation_bar: ^0.8.1 + bottom_navy_bar: ^6.0.0 + provider: ^5.0.0 date_range_picker: ^1.0.7 firebase_auth: ^1.0.1 From 6c260665143b4f103c4bb035d22577cf01dbf0f9 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 5 May 2021 14:52:57 +0300 Subject: [PATCH 10/24] =?UTF-8?q?=D0=98=D0=BD=D0=B8=D1=86=D0=B8=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B2=D1=81=D0=B5?= =?UTF-8?q?=D1=85=20=D0=B2=D1=8B=D1=87=D0=B8=D1=81=D0=BB=D1=8F=D0=B5=D0=BC?= =?UTF-8?q?=D1=8B=D1=85=20=D0=BF=D0=BE=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/old/data/tournament.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/team_c_f/lib/old/data/tournament.dart b/team_c_f/lib/old/data/tournament.dart index 54a0d4b..da5586e 100644 --- a/team_c_f/lib/old/data/tournament.dart +++ b/team_c_f/lib/old/data/tournament.dart @@ -79,7 +79,6 @@ class Tournament with ChangeNotifier { curr.sort((a, b) => a.tour[6].compareTo(b.tour[6])); schedule.addAll([...curr]); - // schedule.sort((a, b) => a.tour.length.compareTo(b.tour.length)); notifyListeners(); }, ); From 16d6f587aefd43e764779ca8910460d4730532bd Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 5 May 2021 14:54:15 +0300 Subject: [PATCH 11/24] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20"=D0=9C=D0=BE=D1=8F=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD=D0=B4=D0=B0"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/assets/images/google.svg | 1 - team_c_f/lib/components/login.dart | 2 +- team_c_f/lib/components/reglament.dart | 2 +- team_c_f/lib/data/currenttour.dart | 8 +- team_c_f/lib/data/data.dart | 158 +++++++++++++----- team_c_f/lib/data/forecast.dart | 41 +++++ team_c_f/lib/data/info.dart | 8 +- team_c_f/lib/data/player.dart | 32 ++-- team_c_f/lib/data/team.dart | 34 ++-- team_c_f/lib/data/tour.dart | 16 +- team_c_f/lib/pages/home.dart | 55 +++--- team_c_f/lib/pages/team.dart | 87 ++++++++++ team_c_f/lib/servises/data.dart | 30 ++-- team_c_f/lib/servises/login.dart | 4 +- team_c_f/lib/servises/selectteam.dart | 10 +- team_c_f/lib/store/login/login.dart | 4 +- team_c_f/lib/store/login/login.g.dart | 4 +- team_c_f/lib/store/myteam/myteam.dart | 22 +++ team_c_f/lib/store/myteam/myteam.g.dart | 49 ++++++ team_c_f/lib/store/selectteam/selectteam.dart | 4 +- team_c_f/lib/store/team/team.dart | 14 ++ team_c_f/lib/store/team/team.g.dart | 33 ++++ team_c_f/lib/views/team.dart | 0 23 files changed, 473 insertions(+), 145 deletions(-) delete mode 100644 team_c_f/assets/images/google.svg create mode 100644 team_c_f/lib/data/forecast.dart create mode 100644 team_c_f/lib/pages/team.dart create mode 100644 team_c_f/lib/store/myteam/myteam.dart create mode 100644 team_c_f/lib/store/myteam/myteam.g.dart create mode 100644 team_c_f/lib/store/team/team.dart create mode 100644 team_c_f/lib/store/team/team.g.dart create mode 100644 team_c_f/lib/views/team.dart diff --git a/team_c_f/assets/images/google.svg b/team_c_f/assets/images/google.svg deleted file mode 100644 index 0b0dfe3..0000000 --- a/team_c_f/assets/images/google.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart index 8f4e8e6..f15dd33 100644 --- a/team_c_f/lib/components/login.dart +++ b/team_c_f/lib/components/login.dart @@ -94,7 +94,7 @@ class LoginView extends StatelessWidget { Provider.of(context) .setDataToSelectTeam(buttonText: 'Зарегистрироваться'); return SelectTeamView( - selectTeam: Provider.of(context).selectTeam, + selectTeam: context.read().selectTeam, ); }, ), diff --git a/team_c_f/lib/components/reglament.dart b/team_c_f/lib/components/reglament.dart index 3b06e25..f16a9f0 100644 --- a/team_c_f/lib/components/reglament.dart +++ b/team_c_f/lib/components/reglament.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:team_c_f/data/info.dart'; class Reglament extends StatelessWidget { - final Info info; + final InfoData info; Reglament({required this.info}); @override Widget build(BuildContext context) { diff --git a/team_c_f/lib/data/currenttour.dart b/team_c_f/lib/data/currenttour.dart index a1c1b74..854915d 100644 --- a/team_c_f/lib/data/currenttour.dart +++ b/team_c_f/lib/data/currenttour.dart @@ -1,6 +1,6 @@ -class CurrentTour { +class CurrentTourData { String round; - CurrentTour({required this.round}); + CurrentTourData({required this.round}); Map toMap() { return { @@ -8,7 +8,7 @@ class CurrentTour { }; } - factory CurrentTour.fromMap({required Map data}){ - return CurrentTour(round: data['Round']); + factory CurrentTourData.fromMap({required Map data}){ + return CurrentTourData(round: data['Round']); } } diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 41fc4d9..2ffd94f 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -4,50 +4,120 @@ import 'package:team_c_f/data/team.dart'; import 'package:team_c_f/data/tour.dart'; class Data { - static CurrentTour? currentTour; - static List? players; - static List? teams; - static List? tours; + static late CurrentTourData currentTour; + static late List players; + static late List teams; + static late List tours; - // Текущий тур (подписка) - // { - // *получаемые поля - // номер тура (строка). - // } - // Игроки - // { - // *получаемые поля - // идентификатор (строка), - // имя (строка), - // название команды (строка), - // лист забитых за тур (лист интов, null при пропуске тура). + static void sortData() { + tours.sort((TourData a, b) => + a.round.compareTo(b.round)); // сортировка туров по порядку - // *вычисляемые поля - // максимум забитых за тур (инт), - // количество забитых за все матчи (инт), - // позиция (инт). - // } - // Команды - // { - // *получаемые поля - // название (строка), - // идентификатор капитана (строка) - // лист участников (лист строк с идентификаторами). + players.sort((PlayerData a, b) => b.goals + .compareTo(a.goals)); // сортировка участников по количеству забитых + players.forEach( + (PlayerData p) { + p.prevPosition = players.indexOf(p); + }, + ); // указание текущей позиции игрока - // *вычисляемые поля - // максимум забитых за тур (инт) - // количество забитых за все матчи (инт), - // количество пропущенных за все матчи (инт), - // победы (инт), - // ничьи (инт), - // поражения (инт), - // очки (инт), - // позиция (инт). - // } - // Туры - // { - // *получаемые поля - // номер тура (строка), - // лист участников (лист типа: команда, забитые). - // } -} \ No newline at end of file + tours.forEach( + (TourData tour) { + int round = tours.indexOf(tour); + tour.team.forEach( + (List pair) { + TeamData home = + teams.where((TeamData team) => team.name == pair[0]).single; + TeamData away = + teams.where((TeamData team) => team.name == pair[1]).single; + if (home.goal[round] == null && away.goal[round] == null) { + home.lose++; + away.lose++; + } else if (home.goal[round] == null) { + home.lose++; + away.win++; + home.missed += away.goal[round]!; + } else if (away.goal[round] == null) { + away.lose++; + home.win++; + away.missed += home.goal[round]!; + } else { + int goalHome = home.goal[round]!; + int goalAway = away.goal[round]!; + home.missed += goalAway; + away.missed += goalHome; + if (goalHome > goalAway) { + home.win++; + away.lose++; + } else if (goalAway > goalHome) { + away.win++; + home.lose++; + } else { + home.draw++; + away.draw++; + } + } + }, + ); + }, + ); // определение wdl для команд и количества пропущенных + teams.sort((TeamData a, b) => (b.goals - b.missed) + .compareTo(a.goals - a.missed)); // сортировка команд по разнице забитых + teams.sort((TeamData a, b) => + b.win.compareTo(a.win)); // сортировка команд по количеству побед + teams.sort((TeamData a, b) => + b.goals.compareTo(a.goals)); // сортировка команд по количеству забитых + teams.sort((TeamData a, b) => + b.points.compareTo(a.points)); // сортировка команд по количеству очков + teams.forEach( + (TeamData t) { + t.prevPosition = teams.indexOf(t); + }, + ); // указание текущей позиции команды + } + // static void initTeams({required List data}){ + // data.sort((TeamData a, b) => a.points.compareTo(b.points)); + // } + + // Текущий тур (подписка) + // { + // *получаемые поля + // номер тура (строка). + // } + // Игроки + // { + // *получаемые поля + // идентификатор (строка), + // имя (строка), + // название команды (строка), + // лист забитых за тур (лист интов, null при пропуске тура). + + // *вычисляемые поля + // максимум забитых за тур (инт), + // количество забитых за все матчи (инт), + // позиция (инт). + // } + // Команды + // { + // *получаемые поля + // название (строка), + // идентификатор капитана (строка) + // лист участников (лист строк с идентификаторами). + + // *вычисляемые поля + // максимум забитых за тур (инт) + // количество забитых за все матчи (инт), + // количество пропущенных за все матчи (инт), + // победы (инт), + // ничьи (инт), + // поражения (инт), + // очки (инт), + // позиция (инт). + // } + // Туры + // { + // *получаемые поля + // номер тура (строка), + // лист участников (лист типа: команда, забитые). + // } +} diff --git a/team_c_f/lib/data/forecast.dart b/team_c_f/lib/data/forecast.dart new file mode 100644 index 0000000..74fcdca --- /dev/null +++ b/team_c_f/lib/data/forecast.dart @@ -0,0 +1,41 @@ +class ForecastData { + final String uid; + final List rate; + final String? team; + final String stage; + int result = 0; + + // - идентификатор игрока, + // - лист прогнозов, + // - название тура, + // - название команды, + // - результат. + + ForecastData({ + required this.uid, + required this.rate, + required this.team, + required this.stage, + }); + + Map toMap() { + return { + 'UserId': uid, + 'Rate': rate, + 'Team': team, + 'Stage': stage, + 'Result': result, + }; + } + + factory ForecastData.fromMap({required Map data}) { + ForecastData f = ForecastData( + uid: data['UserId'], + rate: data['Rate'], + team: data['Team'], + stage: data['Stage'], + ); + f.result = data['Result']; + return f; + } +} diff --git a/team_c_f/lib/data/info.dart b/team_c_f/lib/data/info.dart index 12ee5cc..d53112f 100644 --- a/team_c_f/lib/data/info.dart +++ b/team_c_f/lib/data/info.dart @@ -1,13 +1,13 @@ -class Info { +class InfoData { final List regulations; final String link; - Info({ + InfoData({ required this.regulations, required this.link, }); - factory Info.fromMap({required Map data}) { - return Info( + factory InfoData.fromMap({required Map data}) { + return InfoData( link: data['Link'], regulations: [...data['Regulations']], ); diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/data/player.dart index 11f7c62..29d130d 100644 --- a/team_c_f/lib/data/player.dart +++ b/team_c_f/lib/data/player.dart @@ -1,19 +1,29 @@ -class Player { +class PlayerData { String? docId; final String uid; final String name; final String? team; late List points = []; - int? get maxTour => points.reduce((f, s) => f! < s! ? s : f); - late int goals; - late int position; - // максимум забитых за тур (инт), - // количество забитых за все матчи (инт), - // позиция (инт). + int get maxTour => points.fold( + 0, + (value, current) => current != null + ? current > value + ? current + : value + : value); + int get goals => points.fold( + 0, + (value, current) => value + (current != null ? current : 0), + ); + late int prevPosition; - Player( - {required this.uid, required this.name, required this.team, this.docId}); + PlayerData({ + required this.uid, + required this.name, + required this.team, + this.docId, + }); Map toMap() { return { @@ -24,8 +34,8 @@ class Player { }; } - factory Player.fromMap({required Map data}) { - Player p = Player( + factory PlayerData.fromMap({required Map data}) { + PlayerData p = PlayerData( name: data['Name'], team: data['Team'], uid: data['UserId'], diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/data/team.dart index 2d1c24a..9b930df 100644 --- a/team_c_f/lib/data/team.dart +++ b/team_c_f/lib/data/team.dart @@ -1,19 +1,29 @@ -class Team { +class TeamData { late String docId; final String name; final String uidCapitan; List players = []; + List goal = []; - late int maxTour; - late int goals; - late int missed; - late int win; - late int draw; - late int lose; + int get maxTour => goal.fold( + 0, + (value, current) => current != null + ? current > value + ? current + : value + : value); + int get goals => goal.fold( + 0, + (value, current) => value + (current != null ? current : 0), + ); + int missed = 0; + int win = 0; + int draw = 0; + int lose = 0; int get points => win * 3 + draw; - late int position; + late int prevPosition; - Team({required this.name, required this.uidCapitan}) { + TeamData({required this.name, required this.uidCapitan}) { players.add(this.uidCapitan); } @@ -22,15 +32,17 @@ class Team { 'Name': name, 'Capitan': uidCapitan, 'Players': players, + 'Goal': goal, }; } - factory Team.fromMap({required Map data}) { - Team t = Team( + factory TeamData.fromMap({required Map data}) { + TeamData t = TeamData( name: data['Name'] as String, uidCapitan: data['Capitan'], ); t.players = [...data['Players']]; + t.goal = [...data['Goal']]; return t; } } diff --git a/team_c_f/lib/data/tour.dart b/team_c_f/lib/data/tour.dart index 0c1822c..cf0420c 100644 --- a/team_c_f/lib/data/tour.dart +++ b/team_c_f/lib/data/tour.dart @@ -1,18 +1,20 @@ -class Tour { +class TourData { final String round; - late Map team; // проверить порядок - Tour({required this.round}); + String? name; + late List> team; // проверить порядок + TourData({required this.round, this.name}); - Map toMap(){ + Map toMap() { return { 'Round': round, 'Team': team, + 'Name': name == null ? round : name, }; } - factory Tour.fromMap({required Map data}){ - Tour t = Tour(round: data['Round']); + factory TourData.fromMap({required Map data}) { + TourData t = TourData(round: data['Round'], name: data['Name']); t.team = data['Team']; return t; } -} \ No newline at end of file +} diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index 80bde6c..3b81514 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/pages/team.dart'; import 'package:team_c_f/servises/data.dart'; import 'package:team_c_f/store/home/home.dart'; import 'package:team_c_f/store/login/login.dart'; @@ -14,19 +15,21 @@ class HomePage extends StatelessWidget { DataService().initData(); return SafeArea( child: Scaffold( - body: Column( - children: [ - Data.tours != null - ? Data.tours!.isNotEmpty - ? Text(Data.tours![0].round) - : Text('Туров нет') - : Text('Идёт загрузка'), - ElevatedButton( + body: Observer( + builder: (_) => Column( + children: [ + if (state.selectedIndex == 0) TeamPage(), + Data.tours.isNotEmpty + ? Text(Data.tours[0].round) + : Text('Туров нет'), + ElevatedButton( onPressed: Provider.of(context).googleLogout, child: Text( - 'logout', - )), - ], + '${state.selectedIndex}', + ), + ), + ], + ), ), bottomNavigationBar: Observer( builder: (_) => BottomNavyBar( @@ -34,20 +37,12 @@ class HomePage extends StatelessWidget { onItemSelected: state.selectIndex, selectedIndex: state.selectedIndex, iconSize: 20.0, - items: [ + items: [ BottomNavyBarItem( icon: Icon(Icons.people), - title: Column( - children: [ - Text( - 'Моя', - style: Theme.of(context).textTheme.caption, - ), - Text( - 'команда', - style: Theme.of(context).textTheme.caption, - ), - ], + title: Text( + 'Моя команда', + style: Theme.of(context).textTheme.caption, ), ), BottomNavyBarItem( @@ -59,17 +54,9 @@ class HomePage extends StatelessWidget { ), BottomNavyBarItem( icon: Icon(Icons.add_to_photos), - title: Column( - children: [ - Text( - 'Текущий', - style: Theme.of(context).textTheme.caption, - ), - Text( - 'тур', - style: Theme.of(context).textTheme.caption, - ), - ], + title: Text( + 'Текущий тур', + style: Theme.of(context).textTheme.caption, ), ), BottomNavyBarItem( diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart new file mode 100644 index 0000000..cb3d6df --- /dev/null +++ b/team_c_f/lib/pages/team.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:team_c_f/components/selectteam.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/store/myteam/myteam.dart'; +import 'package:provider/provider.dart'; + +class TeamPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + MyTeam state = MyTeam( + player: Data.players + .where((PlayerData p) => p.uid == context.read().userId) + .single); + return Observer( + builder: (_) => state.team != null + ? Column( + children: [ + ListTile( + leading: CircleAvatar( + // Показывает место в таблице бомбардиров + backgroundColor: Colors.blue[100], + child: Text(state.me.points.toString()), + ), + title: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(state.me.name), // Показывает имя участника + ], + ), + subtitle: state.me.team != null + ? Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Показываем статус игрока, подтвержден ли он капитаном команды + Icon(Icons.done, + color: state.team!.team!.players + .where((String uid) => + uid == state.me.uid) + .length == + 1 + ? Colors.green + : Colors.grey), + Text(state.me.team!), + ], + ) + : SelectTeamView( + selectTeam: context.read().selectTeam), + trailing: CircleAvatar( + backgroundColor: Colors.blue[100], + child: IconButton( + icon: Icon(Icons.exit_to_app), + onPressed: () { + context.read().googleLogout(); + }), + ), + ), + // SizedBox(height: 20), + // if (context + // .watch() + // .me + // .capitan) // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде + // ...context + // .watch() + // .allPlayers + // .where((player) => (!player.confirmed && + // player.team == context.read().myTeam!.title)) + // .map( + // (p) => PlayerToConfirm(player: p), + // ), + // SizedBox(height: 20), + // if (context.read().myTeam != null) + // ShowTeam( + // // Показ информации о моей команде + // team: context.read().myTeam!, + // ) + ], + ) + : Text('Загрузка'), + ); + } +} diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index bfacf82..55508d1 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -14,28 +14,30 @@ class DataService { FirebaseFirestore.instance.collection('currentTour'); final CollectionReference _toursCollection = FirebaseFirestore.instance.collection('tours'); + final CollectionReference _forecastsCollection = + FirebaseFirestore.instance.collection('forecasts'); - void initData() { - getCurrentTour() - .then((CurrentTour currentTour) => Data.currentTour = currentTour); - getPlayers().then((List players) => Data.players = players); - getTeams().then((List teams) => Data.teams = teams); - getTours().then((List tours) => Data.tours = tours); + Future initData() async { + Data.currentTour = await getCurrentTour(); + Data.players = await getPlayers(); + Data.teams = await getTeams(); + Data.tours = await getTours(); + Data.sortData(); } - Future getCurrentTour() { + Future getCurrentTour() { return _currentTourCollection.get().then( - (QuerySnapshot response) => CurrentTour.fromMap( + (QuerySnapshot response) => CurrentTourData.fromMap( data: response.docs.single.data(), ), ); } - Future> getPlayers() { + Future> getPlayers() { return _playersCollection.get().then( (QuerySnapshot response) => response.docs .map( - (QueryDocumentSnapshot doc) => Player.fromMap( + (QueryDocumentSnapshot doc) => PlayerData.fromMap( data: doc.data(), ), ) @@ -43,11 +45,11 @@ class DataService { ); } - Future> getTeams() { + Future> getTeams() { return _teamsCollection.get().then( (QuerySnapshot response) => response.docs .map( - (QueryDocumentSnapshot doc) => Team.fromMap( + (QueryDocumentSnapshot doc) => TeamData.fromMap( data: doc.data(), ), ) @@ -55,11 +57,11 @@ class DataService { ); } - Future> getTours() { + Future> getTours() { return _toursCollection.get().then( (QuerySnapshot response) => response.docs .map( - (QueryDocumentSnapshot doc) => Tour.fromMap( + (QueryDocumentSnapshot doc) => TourData.fromMap( data: doc.data(), ), ) diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart index 3060379..a0d01c7 100644 --- a/team_c_f/lib/servises/login.dart +++ b/team_c_f/lib/servises/login.dart @@ -17,9 +17,9 @@ class LoginService { .then((QuerySnapshot response) => response.docs.isNotEmpty); } - Future getInfo() { + Future getInfo() { return _infoCollection.get().then( - (QuerySnapshot response) => Info.fromMap( + (QuerySnapshot response) => InfoData.fromMap( data: response.docs.single.data(), ), ); diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart index 5331327..d726ed8 100644 --- a/team_c_f/lib/servises/selectteam.dart +++ b/team_c_f/lib/servises/selectteam.dart @@ -16,7 +16,7 @@ class SelectTeamService { .then((response) => response.docs.length == 0); } - Future registrateTeam({required Team team}) async { + Future registrateTeam({required TeamData team}) async { // регистрация команды await _teamsCollection.add(team.toMap()); } @@ -36,21 +36,21 @@ class SelectTeamService { return _teamsCollection.get().then( (QuerySnapshot response) => response.docs .where((QueryDocumentSnapshot doc) => - Team.fromMap(data: doc.data()).players.length < 3) + TeamData.fromMap(data: doc.data()).players.length < 3) .map( - (QueryDocumentSnapshot doc) => Team.fromMap(data: doc.data()).name, + (QueryDocumentSnapshot doc) => TeamData.fromMap(data: doc.data()).name, ) .toList(), ); } - Future registratePlayer({required Player player}) async { + Future registratePlayer({required PlayerData player}) async { // регистрация игрока await _playersCollection.add(player.toMap()); return true; } - Future updatePlayer({required Player player}) async { + Future updatePlayer({required PlayerData player}) async { // обновление игрока (добавление команды) await _playersCollection.doc(player.docId).update( player.toMap(), diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index 32f7c1a..003fb7e 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -18,11 +18,11 @@ abstract class LoginBase with Store { initInfo(); } @observable - Info? info; + InfoData? info; @action void initInfo(){ - LoginService().getInfo().then((Info value) => info = value); + LoginService().getInfo().then((InfoData value) => info = value); } String userId = ''; diff --git a/team_c_f/lib/store/login/login.g.dart b/team_c_f/lib/store/login/login.g.dart index af0401e..7a254a6 100644 --- a/team_c_f/lib/store/login/login.g.dart +++ b/team_c_f/lib/store/login/login.g.dart @@ -20,13 +20,13 @@ mixin _$Login on LoginBase, Store { final _$infoAtom = Atom(name: 'LoginBase.info'); @override - Info? get info { + InfoData? get info { _$infoAtom.reportRead(); return super.info; } @override - set info(Info? value) { + set info(InfoData? value) { _$infoAtom.reportWrite(value, super.info, () { super.info = value; }); diff --git a/team_c_f/lib/store/myteam/myteam.dart b/team_c_f/lib/store/myteam/myteam.dart new file mode 100644 index 0000000..a724e61 --- /dev/null +++ b/team_c_f/lib/store/myteam/myteam.dart @@ -0,0 +1,22 @@ +import 'package:mobx/mobx.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/store/team/team.dart'; +part 'myteam.g.dart'; + +class MyTeam extends _MyTeamBase with _$MyTeam { + MyTeam({required PlayerData player}) : super(me: player); +} + +abstract class _MyTeamBase with Store { + _MyTeamBase({required this.me}) { + team = Team( + team: Data.teams.where((element) => element.name == me.team).single); + } + + @observable + PlayerData me; + + @observable + Team? team; +} diff --git a/team_c_f/lib/store/myteam/myteam.g.dart b/team_c_f/lib/store/myteam/myteam.g.dart new file mode 100644 index 0000000..46d580e --- /dev/null +++ b/team_c_f/lib/store/myteam/myteam.g.dart @@ -0,0 +1,49 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'myteam.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$MyTeam on _MyTeamBase, Store { + final _$meAtom = Atom(name: '_MyTeamBase.me'); + + @override + PlayerData get me { + _$meAtom.reportRead(); + return super.me; + } + + @override + set me(PlayerData value) { + _$meAtom.reportWrite(value, super.me, () { + super.me = value; + }); + } + + final _$teamAtom = Atom(name: '_MyTeamBase.team'); + + @override + Team? get team { + _$teamAtom.reportRead(); + return super.team; + } + + @override + set team(Team? value) { + _$teamAtom.reportWrite(value, super.team, () { + super.team = value; + }); + } + + @override + String toString() { + return ''' +me: ${me}, +team: ${team} + '''; + } +} diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index be9b290..47369ad 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -64,7 +64,7 @@ abstract class _SelectTeamBase with Store { // Выбор команды String? docId = await SelectTeamService().existPlayer(uid: uId); - Player p = Player( + PlayerData p = PlayerData( team: capitan ? teamName : selectedTeam, name: uName, uid: uId, @@ -83,7 +83,7 @@ abstract class _SelectTeamBase with Store { Future registrateTeam() async { // Регистрация команды await SelectTeamService().registrateTeam( - team: Team( + team: TeamData( name: teamName, uidCapitan: uId, ), diff --git a/team_c_f/lib/store/team/team.dart b/team_c_f/lib/store/team/team.dart new file mode 100644 index 0000000..53bc2b1 --- /dev/null +++ b/team_c_f/lib/store/team/team.dart @@ -0,0 +1,14 @@ +import 'package:mobx/mobx.dart'; +import 'package:team_c_f/data/team.dart'; +part 'team.g.dart'; + +class Team extends _TeamBase with _$Team { + Team({required TeamData team}) : super(team: team); +} + +abstract class _TeamBase with Store { + _TeamBase({required this.team}); + + @observable + TeamData? team; +} diff --git a/team_c_f/lib/store/team/team.g.dart b/team_c_f/lib/store/team/team.g.dart new file mode 100644 index 0000000..a183f7a --- /dev/null +++ b/team_c_f/lib/store/team/team.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'team.dart'; + +// ************************************************************************** +// StoreGenerator +// ************************************************************************** + +// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic + +mixin _$Team on _TeamBase, Store { + final _$teamAtom = Atom(name: '_TeamBase.team'); + + @override + TeamData? get team { + _$teamAtom.reportRead(); + return super.team; + } + + @override + set team(TeamData? value) { + _$teamAtom.reportWrite(value, super.team, () { + super.team = value; + }); + } + + @override + String toString() { + return ''' +team: ${team} + '''; + } +} diff --git a/team_c_f/lib/views/team.dart b/team_c_f/lib/views/team.dart new file mode 100644 index 0000000..e69de29 From cf58f275796ad63ab1d4f8e14a3c789de450de07 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 5 May 2021 22:54:07 +0300 Subject: [PATCH 12/24] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D1=82=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=BA=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/confirmedplayer.dart | 57 +++++++++ team_c_f/lib/data/data.dart | 23 +++- team_c_f/lib/data/player.dart | 4 +- team_c_f/lib/main.dart | 8 +- team_c_f/lib/pages/home.dart | 123 +++++++++--------- team_c_f/lib/pages/team.dart | 124 ++++++++++--------- team_c_f/lib/servises/data.dart | 11 +- team_c_f/lib/servises/myteam.dart | 18 +++ team_c_f/lib/store/myteam/myteam.dart | 21 ++++ team_c_f/lib/store/myteam/myteam.g.dart | 29 +++++ team_c_f/lib/store/team/team.dart | 20 ++- team_c_f/lib/store/team/team.g.dart | 20 ++- team_c_f/lib/views/player.dart | 49 ++++++++ team_c_f/lib/views/team.dart | 49 ++++++++ 14 files changed, 419 insertions(+), 137 deletions(-) create mode 100644 team_c_f/lib/components/confirmedplayer.dart create mode 100644 team_c_f/lib/servises/myteam.dart create mode 100644 team_c_f/lib/views/player.dart diff --git a/team_c_f/lib/components/confirmedplayer.dart b/team_c_f/lib/components/confirmedplayer.dart new file mode 100644 index 0000000..303835a --- /dev/null +++ b/team_c_f/lib/components/confirmedplayer.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/store/team/team.dart'; + +class PlayerToConfirm extends StatelessWidget { + // Класс, для отображения неподтвержденных игроков + final PlayerData player; // Неподтвержденный игрок + final Team team; + PlayerToConfirm({Key? key, required this.player, required this.team}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.all(10.0), + child: Text(player.name), + ), + IconButton( + icon: Icon( + Icons.check_box, + size: 30, + color: Colors.green, + ), + onPressed: () { + team.addWin(); + //Data.players.where((PlayerData p) => p.uid == player.uid).single.name = 'New name 4'; + Fluttertoast.showToast( + msg: '${player.name} добавлен в вашу команду', + ); + }, + ), + IconButton( + icon: Icon( + Icons.cancel, + size: 30, + color: Colors.red, + ), + onPressed: () { + // context + // .read() + // .confirmPlayer(uid: player.uid, confirm: false); + Fluttertoast.showToast( + msg: 'Заявка отклонена', + ); + }, + ), + ], + ), + ); + } +} diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 2ffd94f..b366b6a 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -1,23 +1,38 @@ +import 'package:flutter/material.dart'; import 'package:team_c_f/data/currenttour.dart'; import 'package:team_c_f/data/player.dart'; import 'package:team_c_f/data/team.dart'; import 'package:team_c_f/data/tour.dart'; +import 'package:team_c_f/servises/data.dart'; + +class Data with ChangeNotifier { + bool downloadSuccessful = false; + + Data() { + DataService().initData().then((result) { + sortTour(); + sortData(); + downloadSuccessful = result; + notifyListeners(); + }); + } -class Data { static late CurrentTourData currentTour; static late List players; static late List teams; static late List tours; - static void sortData() { + static void sortTour() { tours.sort((TourData a, b) => a.round.compareTo(b.round)); // сортировка туров по порядку + } + static void sortData() { players.sort((PlayerData a, b) => b.goals .compareTo(a.goals)); // сортировка участников по количеству забитых players.forEach( (PlayerData p) { - p.prevPosition = players.indexOf(p); + p.prevPosition = players.indexOf(p) + 1; }, ); // указание текущей позиции игрока @@ -71,7 +86,7 @@ class Data { b.points.compareTo(a.points)); // сортировка команд по количеству очков teams.forEach( (TeamData t) { - t.prevPosition = teams.indexOf(t); + t.prevPosition = teams.indexOf(t) + 1; }, ); // указание текущей позиции команды } diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/data/player.dart index 29d130d..6d7dd82 100644 --- a/team_c_f/lib/data/player.dart +++ b/team_c_f/lib/data/player.dart @@ -1,8 +1,8 @@ class PlayerData { String? docId; final String uid; - final String name; - final String? team; + String name; + String? team; late List points = []; int get maxTour => points.fold( diff --git a/team_c_f/lib/main.dart b/team_c_f/lib/main.dart index d4e1f39..ec9dff9 100644 --- a/team_c_f/lib/main.dart +++ b/team_c_f/lib/main.dart @@ -3,6 +3,7 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:onesignal_flutter/onesignal_flutter.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/pages/login.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/pages/home.dart'; @@ -22,6 +23,7 @@ myApp() async { home: MultiProvider( providers: [ Provider(create: (_) => Login()), + ChangeNotifierProvider(create: (_) => Data()), ], child: FirstPage(), ), @@ -35,8 +37,8 @@ class FirstPage extends StatelessWidget { @override Widget build(BuildContext context) { return Observer( - builder: (_) => context.read().registrateInApp - ? HomePage() - : LoginPage()); + builder: (_) => + context.read().registrateInApp ? HomePage() : LoginPage(), + ); } } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index 3b81514..c63f91a 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -12,71 +12,74 @@ class HomePage extends StatelessWidget { static Home state = Home(); @override Widget build(BuildContext context) { - DataService().initData(); return SafeArea( - child: Scaffold( - body: Observer( - builder: (_) => Column( - children: [ - if (state.selectedIndex == 0) TeamPage(), - Data.tours.isNotEmpty - ? Text(Data.tours[0].round) - : Text('Туров нет'), - ElevatedButton( - onPressed: Provider.of(context).googleLogout, - child: Text( - '${state.selectedIndex}', + child: context.watch().downloadSuccessful + ? Scaffold( + body: Observer( + builder: (_) => Column( + children: [ + if (state.selectedIndex == 0) TeamPage(), + Data.tours.isNotEmpty + ? Text(Data.tours[0].round) + : Text('Туров нет'), + ElevatedButton( + onPressed: Provider.of(context).googleLogout, + child: Text( + '${state.selectedIndex}', + ), + ), + ], ), ), - ], - ), - ), - bottomNavigationBar: Observer( - builder: (_) => BottomNavyBar( - // Бар с вариантами выбора страниц - onItemSelected: state.selectIndex, - selectedIndex: state.selectedIndex, - iconSize: 20.0, - items: [ - BottomNavyBarItem( - icon: Icon(Icons.people), - title: Text( - 'Моя команда', - style: Theme.of(context).textTheme.caption, + bottomNavigationBar: Observer( + builder: (_) => BottomNavyBar( + // Бар с вариантами выбора страниц + onItemSelected: state.selectIndex, + selectedIndex: state.selectedIndex, + iconSize: 20.0, + items: [ + BottomNavyBarItem( + icon: Icon(Icons.people), + title: Text( + 'Моя команда', + style: Theme.of(context).textTheme.caption, + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.calendar_today), + title: Text( + 'Календарь', + style: Theme.of(context).textTheme.caption, + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.add_to_photos), + title: Text( + 'Текущий тур', + style: Theme.of(context).textTheme.caption, + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.toc), + title: Text( + 'Таблица', + style: Theme.of(context).textTheme.caption, + ), + ), + BottomNavyBarItem( + icon: Icon(Icons.list_alt), + title: Text( + 'Бомбардиры', + style: Theme.of(context).textTheme.caption, + ), + ), + ], ), ), - BottomNavyBarItem( - icon: Icon(Icons.calendar_today), - title: Text( - 'Календарь', - style: Theme.of(context).textTheme.caption, - ), - ), - BottomNavyBarItem( - icon: Icon(Icons.add_to_photos), - title: Text( - 'Текущий тур', - style: Theme.of(context).textTheme.caption, - ), - ), - BottomNavyBarItem( - icon: Icon(Icons.toc), - title: Text( - 'Таблица', - style: Theme.of(context).textTheme.caption, - ), - ), - BottomNavyBarItem( - icon: Icon(Icons.list_alt), - title: Text( - 'Бомбардиры', - style: Theme.of(context).textTheme.caption, - ), - ), - ], - ), - ), - ), + ) + : Scaffold( + body: Text('DOWNLOADING'), + ), ); } } diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index cb3d6df..f207349 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:team_c_f/components/confirmedplayer.dart'; import 'package:team_c_f/components/selectteam.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/team.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/store/myteam/myteam.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/views/team.dart'; class TeamPage extends StatelessWidget { @override @@ -19,66 +20,71 @@ class TeamPage extends StatelessWidget { builder: (_) => state.team != null ? Column( children: [ - ListTile( - leading: CircleAvatar( - // Показывает место в таблице бомбардиров - backgroundColor: Colors.blue[100], - child: Text(state.me.points.toString()), - ), - title: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(state.me.name), // Показывает имя участника - ], - ), - subtitle: state.me.team != null - ? Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // Показываем статус игрока, подтвержден ли он капитаном команды - Icon(Icons.done, - color: state.team!.team!.players - .where((String uid) => - uid == state.me.uid) - .length == - 1 - ? Colors.green - : Colors.grey), - Text(state.me.team!), - ], - ) - : SelectTeamView( - selectTeam: context.read().selectTeam), - trailing: CircleAvatar( - backgroundColor: Colors.blue[100], - child: IconButton( - icon: Icon(Icons.exit_to_app), - onPressed: () { - context.read().googleLogout(); - }), + Card( + color: Colors.red[100], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100)), + child: ListTile( + leading: CircleAvatar( + // Показывает место в таблице бомбардиров + backgroundColor: Colors.blue[100], + child: Text(state.me.prevPosition.toString()), + ), + title: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(state.me.name), // Показывает имя участника + ], + ), + subtitle: state.me.team != null + ? Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Показываем статус игрока, подтвержден ли он капитаном команды + Icon(Icons.done, + color: state.team!.team.players + .where((String uid) => + uid == state.me.uid) + .length == + 1 + ? Colors.green + : Colors.grey), + Text(state.me.team!), + ], + ) + : SelectTeamView( + selectTeam: context.read().selectTeam), + trailing: CircleAvatar( + backgroundColor: Colors.blue[100], + child: IconButton( + icon: Icon(Icons.exit_to_app), + onPressed: () { + context.read().googleLogout(); + }), + ), ), ), - // SizedBox(height: 20), - // if (context - // .watch() - // .me - // .capitan) // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде - // ...context - // .watch() - // .allPlayers - // .where((player) => (!player.confirmed && - // player.team == context.read().myTeam!.title)) - // .map( - // (p) => PlayerToConfirm(player: p), - // ), - // SizedBox(height: 20), - // if (context.read().myTeam != null) - // ShowTeam( - // // Показ информации о моей команде - // team: context.read().myTeam!, - // ) + if (state.team != null) + if (state.team!.team.uidCapitan == state.me.uid) + // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + ...state.unconfirmPlayer.map( + (PlayerData p) => + PlayerToConfirm(player: p, team: state.team!), + ), + ], + ), + ), + if (state.team != null) + ShowTeam( + // Показ информации о моей команде + team: state.team!.team, + ), ], ) : Text('Загрузка'), diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index 55508d1..6e76ad3 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -5,7 +5,8 @@ import 'package:team_c_f/data/player.dart'; import 'package:team_c_f/data/team.dart'; import 'package:team_c_f/data/tour.dart'; -class DataService { +class DataService{ + final CollectionReference _playersCollection = FirebaseFirestore.instance.collection('players'); final CollectionReference _teamsCollection = @@ -14,15 +15,15 @@ class DataService { FirebaseFirestore.instance.collection('currentTour'); final CollectionReference _toursCollection = FirebaseFirestore.instance.collection('tours'); - final CollectionReference _forecastsCollection = - FirebaseFirestore.instance.collection('forecasts'); + // final CollectionReference _forecastsCollection = + // FirebaseFirestore.instance.collection('forecasts'); - Future initData() async { + Future initData() async { Data.currentTour = await getCurrentTour(); Data.players = await getPlayers(); Data.teams = await getTeams(); Data.tours = await getTours(); - Data.sortData(); + return true; } Future getCurrentTour() { diff --git a/team_c_f/lib/servises/myteam.dart b/team_c_f/lib/servises/myteam.dart new file mode 100644 index 0000000..30fc604 --- /dev/null +++ b/team_c_f/lib/servises/myteam.dart @@ -0,0 +1,18 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/data/team.dart'; + +class MyTeamService { + final CollectionReference _playersCollection = + FirebaseFirestore.instance.collection('players'); + final CollectionReference _teamsCollection = + FirebaseFirestore.instance.collection('teams'); + + void updatePlayer({required PlayerData player}) { + _playersCollection.doc(player.docId).update(player.toMap()); + } + + void updateTeam({required TeamData team}) { + _teamsCollection.doc(team.docId).update(team.toMap()); + } +} diff --git a/team_c_f/lib/store/myteam/myteam.dart b/team_c_f/lib/store/myteam/myteam.dart index a724e61..1301afc 100644 --- a/team_c_f/lib/store/myteam/myteam.dart +++ b/team_c_f/lib/store/myteam/myteam.dart @@ -12,6 +12,27 @@ abstract class _MyTeamBase with Store { _MyTeamBase({required this.me}) { team = Team( team: Data.teams.where((element) => element.name == me.team).single); + if (me.uid == team!.team.uidCapitan) { + List inTeam = []; + inTeam.addAll( + Data.players.where((PlayerData p) => p.team == team!.team.name), + ); + unconfirmPlayer.addAll( + inTeam.where( + (PlayerData p) => + team!.team.players.every((String uid) => uid != p.uid), + ), + ); + } + } + + @observable + List unconfirmPlayer = []; + + @action + void confirm({required String uid, required bool confirm}) { + unconfirmPlayer.removeWhere((PlayerData p) => p.uid == uid); + if (confirm) team!.team.players.add(uid); } @observable diff --git a/team_c_f/lib/store/myteam/myteam.g.dart b/team_c_f/lib/store/myteam/myteam.g.dart index 46d580e..e18002d 100644 --- a/team_c_f/lib/store/myteam/myteam.g.dart +++ b/team_c_f/lib/store/myteam/myteam.g.dart @@ -9,6 +9,21 @@ part of 'myteam.dart'; // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$MyTeam on _MyTeamBase, Store { + final _$unconfirmPlayerAtom = Atom(name: '_MyTeamBase.unconfirmPlayer'); + + @override + List get unconfirmPlayer { + _$unconfirmPlayerAtom.reportRead(); + return super.unconfirmPlayer; + } + + @override + set unconfirmPlayer(List value) { + _$unconfirmPlayerAtom.reportWrite(value, super.unconfirmPlayer, () { + super.unconfirmPlayer = value; + }); + } + final _$meAtom = Atom(name: '_MyTeamBase.me'); @override @@ -39,9 +54,23 @@ mixin _$MyTeam on _MyTeamBase, Store { }); } + final _$_MyTeamBaseActionController = ActionController(name: '_MyTeamBase'); + + @override + void confirm({required String uid, required bool confirm}) { + final _$actionInfo = + _$_MyTeamBaseActionController.startAction(name: '_MyTeamBase.confirm'); + try { + return super.confirm(uid: uid, confirm: confirm); + } finally { + _$_MyTeamBaseActionController.endAction(_$actionInfo); + } + } + @override String toString() { return ''' +unconfirmPlayer: ${unconfirmPlayer}, me: ${me}, team: ${team} '''; diff --git a/team_c_f/lib/store/team/team.dart b/team_c_f/lib/store/team/team.dart index 53bc2b1..9ce1363 100644 --- a/team_c_f/lib/store/team/team.dart +++ b/team_c_f/lib/store/team/team.dart @@ -1,4 +1,6 @@ import 'package:mobx/mobx.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/data/player.dart'; import 'package:team_c_f/data/team.dart'; part 'team.g.dart'; @@ -7,8 +9,22 @@ class Team extends _TeamBase with _$Team { } abstract class _TeamBase with Store { - _TeamBase({required this.team}); + _TeamBase({required this.team}) { + team.players.forEach( + (String uid) { + players.add(Data.players.where((PlayerData p) => p.uid == uid).single); + }, + ); + } @observable - TeamData? team; + List players = []; + + @observable + late TeamData team; + + @action + void addWin(){ + team.win++; + } } diff --git a/team_c_f/lib/store/team/team.g.dart b/team_c_f/lib/store/team/team.g.dart index a183f7a..2d9a6db 100644 --- a/team_c_f/lib/store/team/team.g.dart +++ b/team_c_f/lib/store/team/team.g.dart @@ -9,16 +9,31 @@ part of 'team.dart'; // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$Team on _TeamBase, Store { + final _$playersAtom = Atom(name: '_TeamBase.players'); + + @override + List get players { + _$playersAtom.reportRead(); + return super.players; + } + + @override + set players(List value) { + _$playersAtom.reportWrite(value, super.players, () { + super.players = value; + }); + } + final _$teamAtom = Atom(name: '_TeamBase.team'); @override - TeamData? get team { + TeamData get team { _$teamAtom.reportRead(); return super.team; } @override - set team(TeamData? value) { + set team(TeamData value) { _$teamAtom.reportWrite(value, super.team, () { super.team = value; }); @@ -27,6 +42,7 @@ mixin _$Team on _TeamBase, Store { @override String toString() { return ''' +players: ${players}, team: ${team} '''; } diff --git a/team_c_f/lib/views/player.dart b/team_c_f/lib/views/player.dart new file mode 100644 index 0000000..22f50ae --- /dev/null +++ b/team_c_f/lib/views/player.dart @@ -0,0 +1,49 @@ +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:team_c_f/data/player.dart'; + +class ShowPlayer extends StatelessWidget { + // Класс отображающий информацию об указанном игроке + final PlayerData player; + ShowPlayer({Key? key, required this.player}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: InkWell( + onLongPress: () async { + // if (context.read().me.capitan && + // (await showAlertDialog( + // context: context, + // title: 'Изменение состава', + // message: 'Удалить ${player.name}', + // actions: [ + // AlertDialogAction( + // key: true, + // label: 'Да, удалить', + // isDefaultAction: true, + // ), + // AlertDialogAction( + // key: false, + // label: 'Отмена', + // isDestructiveAction: true, + // ), + // ], + // ))!) { + // context.read().removePlayerFromMyTeam(uid: player.uid); + // } + }, + child: Card( + child: ListTile( + leading: CircleAvatar( + child: Text(player.prevPosition.toString()), + ), + title: Text(player.name), + trailing: Text(player.goals.toString()), + //showPoints(player.points)), + ), + ), + ), + ); + } +} diff --git a/team_c_f/lib/views/team.dart b/team_c_f/lib/views/team.dart index e69de29..3b02957 100644 --- a/team_c_f/lib/views/team.dart +++ b/team_c_f/lib/views/team.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/views/player.dart'; + +class ShowTeam extends StatelessWidget { + // Класс отображения информации об указанной команде + final TeamData team; // Команда + ShowTeam({Key? key, required this.team}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: Column( + children: [ + Card( + child: ListTile( + // Информация о команде + leading: CircleAvatar( + child: Text( + team.prevPosition.toString(), + ), + ), + title: Text(team.name), + trailing: Text( + team.points.toString() + //showPoints(team.points), + ), + ), + ), + Container( + // Информация об участниках команды + margin: const EdgeInsets.all(8.0), + child: Column( + children: [ + ...team.players.map( + (String uid) => ShowPlayer( + player: Data.players + .where((player) => player.uid == uid) + .first), + ), + ], + ), + ), + ], + ), + ); + } +} From e8775da7df6cfe43c376063cfd0fa6cb4aad5a1b Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 6 May 2021 23:53:00 +0300 Subject: [PATCH 13/24] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=20=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=86=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD?= =?UTF-8?q?=D0=B4=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/pages/team.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index f207349..3687f95 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -81,9 +81,11 @@ class TeamPage extends StatelessWidget { ), ), if (state.team != null) - ShowTeam( - // Показ информации о моей команде - team: state.team!.team, + Observer( + builder: (_) => ShowTeam( + // Показ информации о моей команде + team: state.team!.team, + ), ), ], ) From d3f5e61791e6dce5dc1110a736353daa1b4388df Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 7 May 2021 20:28:54 +0300 Subject: [PATCH 14/24] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=20Bloc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/confirmedplayer.dart | 3 +- team_c_f/lib/components/reglament.dart | 2 +- team_c_f/lib/data/data.dart | 8 +++--- .../lib/{data => models}/currenttour.dart | 0 team_c_f/lib/{data => models}/forecast.dart | 0 team_c_f/lib/{data => models}/info.dart | 0 team_c_f/lib/{data => models}/player.dart | 0 team_c_f/lib/{data => models}/team.dart | 0 team_c_f/lib/{data => models}/tour.dart | 0 team_c_f/lib/pages/team.dart | 10 +++---- team_c_f/lib/servises/data.dart | 8 +++--- team_c_f/lib/servises/login.dart | 2 +- team_c_f/lib/servises/myteam.dart | 4 +-- team_c_f/lib/servises/selectteam.dart | 4 +-- team_c_f/lib/store/login/login.dart | 2 +- team_c_f/lib/store/myteam/myteam.dart | 2 +- team_c_f/lib/store/selectteam/selectteam.dart | 4 +-- team_c_f/lib/store/state.dart | 0 team_c_f/lib/store/team/team.dart | 4 +-- team_c_f/lib/views/player.dart | 2 +- team_c_f/lib/views/team.dart | 28 ++++++++++--------- team_c_f/pubspec.lock | 7 +++++ team_c_f/pubspec.yaml | 2 +- 23 files changed, 49 insertions(+), 43 deletions(-) rename team_c_f/lib/{data => models}/currenttour.dart (100%) rename team_c_f/lib/{data => models}/forecast.dart (100%) rename team_c_f/lib/{data => models}/info.dart (100%) rename team_c_f/lib/{data => models}/player.dart (100%) rename team_c_f/lib/{data => models}/team.dart (100%) rename team_c_f/lib/{data => models}/tour.dart (100%) create mode 100644 team_c_f/lib/store/state.dart diff --git a/team_c_f/lib/components/confirmedplayer.dart b/team_c_f/lib/components/confirmedplayer.dart index 303835a..8c1460f 100644 --- a/team_c_f/lib/components/confirmedplayer.dart +++ b/team_c_f/lib/components/confirmedplayer.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/store/team/team.dart'; class PlayerToConfirm extends StatelessWidget { @@ -29,7 +29,6 @@ class PlayerToConfirm extends StatelessWidget { ), onPressed: () { team.addWin(); - //Data.players.where((PlayerData p) => p.uid == player.uid).single.name = 'New name 4'; Fluttertoast.showToast( msg: '${player.name} добавлен в вашу команду', ); diff --git a/team_c_f/lib/components/reglament.dart b/team_c_f/lib/components/reglament.dart index f16a9f0..cbab609 100644 --- a/team_c_f/lib/components/reglament.dart +++ b/team_c_f/lib/components/reglament.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/info.dart'; +import 'package:team_c_f/models/info.dart'; class Reglament extends StatelessWidget { final InfoData info; diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index b366b6a..4d5894b 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/data/currenttour.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/data/tour.dart'; +import 'package:team_c_f/models/currenttour.dart'; +import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/servises/data.dart'; class Data with ChangeNotifier { diff --git a/team_c_f/lib/data/currenttour.dart b/team_c_f/lib/models/currenttour.dart similarity index 100% rename from team_c_f/lib/data/currenttour.dart rename to team_c_f/lib/models/currenttour.dart diff --git a/team_c_f/lib/data/forecast.dart b/team_c_f/lib/models/forecast.dart similarity index 100% rename from team_c_f/lib/data/forecast.dart rename to team_c_f/lib/models/forecast.dart diff --git a/team_c_f/lib/data/info.dart b/team_c_f/lib/models/info.dart similarity index 100% rename from team_c_f/lib/data/info.dart rename to team_c_f/lib/models/info.dart diff --git a/team_c_f/lib/data/player.dart b/team_c_f/lib/models/player.dart similarity index 100% rename from team_c_f/lib/data/player.dart rename to team_c_f/lib/models/player.dart diff --git a/team_c_f/lib/data/team.dart b/team_c_f/lib/models/team.dart similarity index 100% rename from team_c_f/lib/data/team.dart rename to team_c_f/lib/models/team.dart diff --git a/team_c_f/lib/data/tour.dart b/team_c_f/lib/models/tour.dart similarity index 100% rename from team_c_f/lib/data/tour.dart rename to team_c_f/lib/models/tour.dart diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index 3687f95..564f25a 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -3,7 +3,7 @@ import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:team_c_f/components/confirmedplayer.dart'; import 'package:team_c_f/components/selectteam.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/store/myteam/myteam.dart'; import 'package:provider/provider.dart'; @@ -81,11 +81,9 @@ class TeamPage extends StatelessWidget { ), ), if (state.team != null) - Observer( - builder: (_) => ShowTeam( - // Показ информации о моей команде - team: state.team!.team, - ), + ShowTeam( + // Показ информации о моей команде + team: state.team!, ), ], ) diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index 6e76ad3..050549d 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -1,9 +1,9 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/data/currenttour.dart'; +import 'package:team_c_f/models/currenttour.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/data/tour.dart'; +import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/models/tour.dart'; class DataService{ diff --git a/team_c_f/lib/servises/login.dart b/team_c_f/lib/servises/login.dart index a0d01c7..eb61631 100644 --- a/team_c_f/lib/servises/login.dart +++ b/team_c_f/lib/servises/login.dart @@ -1,5 +1,5 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/data/info.dart'; +import 'package:team_c_f/models/info.dart'; class LoginService { final CollectionReference _playersCollection = diff --git a/team_c_f/lib/servises/myteam.dart b/team_c_f/lib/servises/myteam.dart index 30fc604..e9bc404 100644 --- a/team_c_f/lib/servises/myteam.dart +++ b/team_c_f/lib/servises/myteam.dart @@ -1,6 +1,6 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/models/team.dart'; class MyTeamService { final CollectionReference _playersCollection = diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart index d726ed8..49bffe7 100644 --- a/team_c_f/lib/servises/selectteam.dart +++ b/team_c_f/lib/servises/selectteam.dart @@ -1,6 +1,6 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/models/player.dart'; class SelectTeamService { final CollectionReference _playersCollection = diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index 003fb7e..8f924fe 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -1,7 +1,7 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:mobx/mobx.dart'; -import 'package:team_c_f/data/info.dart'; +import 'package:team_c_f/models/info.dart'; import 'package:team_c_f/servises/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; diff --git a/team_c_f/lib/store/myteam/myteam.dart b/team_c_f/lib/store/myteam/myteam.dart index 1301afc..21cdbf7 100644 --- a/team_c_f/lib/store/myteam/myteam.dart +++ b/team_c_f/lib/store/myteam/myteam.dart @@ -1,6 +1,6 @@ import 'package:mobx/mobx.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/store/team/team.dart'; part 'myteam.g.dart'; diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index 47369ad..1d12db3 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -1,7 +1,7 @@ import 'package:mobx/mobx.dart'; import 'package:team_c_f/servises/selectteam.dart'; -import 'package:team_c_f/data/team.dart'; -import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/models/player.dart'; part 'selectteam.g.dart'; class SelectTeam = _SelectTeamBase with _$SelectTeam; diff --git a/team_c_f/lib/store/state.dart b/team_c_f/lib/store/state.dart new file mode 100644 index 0000000..e69de29 diff --git a/team_c_f/lib/store/team/team.dart b/team_c_f/lib/store/team/team.dart index 9ce1363..1060683 100644 --- a/team_c_f/lib/store/team/team.dart +++ b/team_c_f/lib/store/team/team.dart @@ -1,7 +1,7 @@ import 'package:mobx/mobx.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/player.dart'; -import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/models/team.dart'; part 'team.g.dart'; class Team extends _TeamBase with _$Team { diff --git a/team_c_f/lib/views/player.dart b/team_c_f/lib/views/player.dart index 22f50ae..4f435c5 100644 --- a/team_c_f/lib/views/player.dart +++ b/team_c_f/lib/views/player.dart @@ -1,6 +1,6 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter/material.dart'; -import 'package:team_c_f/data/player.dart'; +import 'package:team_c_f/models/player.dart'; class ShowPlayer extends StatelessWidget { // Класс отображающий информацию об указанном игроке diff --git a/team_c_f/lib/views/team.dart b/team_c_f/lib/views/team.dart index 3b02957..82c29bc 100644 --- a/team_c_f/lib/views/team.dart +++ b/team_c_f/lib/views/team.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/data/team.dart'; +import 'package:team_c_f/store/team/team.dart'; import 'package:team_c_f/views/player.dart'; class ShowTeam extends StatelessWidget { // Класс отображения информации об указанной команде - final TeamData team; // Команда + final Team team; // Команда ShowTeam({Key? key, required this.team}) : super(key: key); @override @@ -14,17 +15,18 @@ class ShowTeam extends StatelessWidget { child: Column( children: [ Card( - child: ListTile( - // Информация о команде - leading: CircleAvatar( - child: Text( - team.prevPosition.toString(), + child: Observer( + builder: (_) => ListTile( + // Информация о команде + leading: CircleAvatar( + child: Text( + team.team.prevPosition.toString(), + ), ), - ), - title: Text(team.name), - trailing: Text( - team.points.toString() - //showPoints(team.points), + title: Text(team.team.name), + trailing: Text(team.team.points.toString() + //showPoints(team.points), + ), ), ), ), @@ -33,7 +35,7 @@ class ShowTeam extends StatelessWidget { margin: const EdgeInsets.all(8.0), child: Column( children: [ - ...team.players.map( + ...team.team.players.map( (String uid) => ShowPlayer( player: Data.players .where((player) => player.uid == uid) diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index db89276..e2716ba 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -555,6 +555,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" + redux: + dependency: "direct main" + description: + name: redux + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" shelf: dependency: transitive description: diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index 1c4e309..0ee0eac 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: http: ^0.13.1 html: ^0.15.0 carousel_slider: ^3.0.0 - + redux: ^5.0.0 custom_navigation_bar: ^0.8.1 bottom_navy_bar: ^6.0.0 From 2401c9d72344a58d3295ed3d4117b9a3ae96852f Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 10 May 2021 11:20:59 +0300 Subject: [PATCH 15/24] =?UTF-8?q?=D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BC=D0=BE=D1=8F=20=D0=BA=D0=BE=D0=BC?= =?UTF-8?q?=D0=B0=D0=BD=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/createschedule.dart | 12 ++ team_c_f/lib/components/login.dart | 3 +- team_c_f/lib/components/reglament.dart | 10 +- team_c_f/lib/components/selectteam.dart | 16 ++- ...rmedplayer.dart => unconfirmedplayer.dart} | 19 +-- team_c_f/lib/data/data.dart | 11 ++ team_c_f/lib/models/currenttour.dart | 7 +- team_c_f/lib/models/player.dart | 3 +- team_c_f/lib/models/team.dart | 3 +- team_c_f/lib/old/view/team.dart | 2 +- team_c_f/lib/pages/home.dart | 129 +++++++++++------- team_c_f/lib/pages/schedule.dart | 95 +++++++++++++ team_c_f/lib/pages/team.dart | 90 ++++++------ team_c_f/lib/servises/data.dart | 6 +- team_c_f/lib/servises/myteam.dart | 23 +++- .../state.dart => servises/schedule.dart} | 0 team_c_f/lib/servises/selectteam.dart | 11 +- team_c_f/lib/servises/servises.dart | 17 +++ team_c_f/lib/store/bloc/createschedule.dart | 0 team_c_f/lib/store/bloc/myteam.dart | 33 +++++ team_c_f/lib/store/bloc/schedule.dart | 40 ++++++ team_c_f/lib/store/components/myteam.dart | 81 +++++++++++ team_c_f/lib/store/components/schedule.dart | 20 +++ team_c_f/lib/store/components/team.dart | 14 ++ team_c_f/lib/store/components/tour.dart | 11 ++ .../store/components/unconfirmedplayer.dart | 10 ++ team_c_f/lib/store/login/login.dart | 7 +- team_c_f/lib/store/selectteam/selectteam.dart | 2 + team_c_f/lib/views/player.dart | 50 ++++--- team_c_f/lib/views/team.dart | 9 +- team_c_f/pubspec.lock | 21 ++- team_c_f/pubspec.yaml | 2 +- 32 files changed, 586 insertions(+), 171 deletions(-) create mode 100644 team_c_f/lib/components/createschedule.dart rename team_c_f/lib/components/{confirmedplayer.dart => unconfirmedplayer.dart} (67%) create mode 100644 team_c_f/lib/pages/schedule.dart rename team_c_f/lib/{store/state.dart => servises/schedule.dart} (100%) create mode 100644 team_c_f/lib/servises/servises.dart create mode 100644 team_c_f/lib/store/bloc/createschedule.dart create mode 100644 team_c_f/lib/store/bloc/myteam.dart create mode 100644 team_c_f/lib/store/bloc/schedule.dart create mode 100644 team_c_f/lib/store/components/myteam.dart create mode 100644 team_c_f/lib/store/components/schedule.dart create mode 100644 team_c_f/lib/store/components/team.dart create mode 100644 team_c_f/lib/store/components/tour.dart create mode 100644 team_c_f/lib/store/components/unconfirmedplayer.dart diff --git a/team_c_f/lib/components/createschedule.dart b/team_c_f/lib/components/createschedule.dart new file mode 100644 index 0000000..49c97bc --- /dev/null +++ b/team_c_f/lib/components/createschedule.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class CreateScheduleView extends StatelessWidget { + const CreateScheduleView({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + child: Text('Нет расписания'), + ); + } +} \ No newline at end of file diff --git a/team_c_f/lib/components/login.dart b/team_c_f/lib/components/login.dart index f15dd33..24e7737 100644 --- a/team_c_f/lib/components/login.dart +++ b/team_c_f/lib/components/login.dart @@ -53,7 +53,7 @@ class LoginView extends StatelessWidget { if (login.info != null) Navigator.of(context) .push(MaterialPageRoute( - builder: (_) => Reglament(info: login.info!))) + builder: (_) => ReglamentView(info: login.info!))) .then((value) => login.changeName(value!.toString())); }, child: Text('Правила конкурса'), @@ -95,6 +95,7 @@ class LoginView extends StatelessWidget { .setDataToSelectTeam(buttonText: 'Зарегистрироваться'); return SelectTeamView( selectTeam: context.read().selectTeam, + updateMyTeam: false, ); }, ), diff --git a/team_c_f/lib/components/reglament.dart b/team_c_f/lib/components/reglament.dart index cbab609..fa5f6db 100644 --- a/team_c_f/lib/components/reglament.dart +++ b/team_c_f/lib/components/reglament.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:team_c_f/models/info.dart'; -class Reglament extends StatelessWidget { +class ReglamentView extends StatelessWidget { final InfoData info; - Reglament({required this.info}); + ReglamentView({required this.info}); @override Widget build(BuildContext context) { return MaterialApp( @@ -17,12 +17,6 @@ class Reglament extends StatelessWidget { Navigator.of(context).pop(true); }, ), - // IconButton( - // icon: Icon(Icons.arrow_back), - // onPressed: () { - // Navigator.of(context).pop(); - // }, - // ), SizedBox(width: 20), Text('Правила конкурса'), ], diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index 344cc1b..751a7e7 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -1,16 +1,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/store/bloc/myteam.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; class SelectTeamView extends StatelessWidget { // Класс отображения выбора команды или регистрации новой final SelectTeam selectTeam; + final bool updateMyTeam; const SelectTeamView({ Key? key, required this.selectTeam, + required this.updateMyTeam, }) : super(key: key); @override @@ -135,7 +139,11 @@ class SelectTeamView extends StatelessWidget { selectTeam.registrateTeam().then( (_) { context.read().validateInApp(); - context.read().clearData(); + context.read().clearData(); + if (updateMyTeam) + context + .read() + .add(MyTeamEvent.reset); }, ); } @@ -146,7 +154,11 @@ class SelectTeamView extends StatelessWidget { selectTeam.assertTeam().then( (_) { context.read().validateInApp(); - context.read().clearData(); + context.read().clearData(); + if (updateMyTeam) + context + .read() + .add(MyTeamEvent.reset); }, ); } diff --git a/team_c_f/lib/components/confirmedplayer.dart b/team_c_f/lib/components/unconfirmedplayer.dart similarity index 67% rename from team_c_f/lib/components/confirmedplayer.dart rename to team_c_f/lib/components/unconfirmedplayer.dart index 8c1460f..345937f 100644 --- a/team_c_f/lib/components/confirmedplayer.dart +++ b/team_c_f/lib/components/unconfirmedplayer.dart @@ -2,16 +2,19 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:team_c_f/store/components/unconfirmedplayer.dart'; +import 'package:provider/provider.dart'; import 'package:team_c_f/store/team/team.dart'; -class PlayerToConfirm extends StatelessWidget { +class UnconfirmedPlayerView extends StatelessWidget { // Класс, для отображения неподтвержденных игроков - final PlayerData player; // Неподтвержденный игрок - final Team team; - PlayerToConfirm({Key? key, required this.player, required this.team}) : super(key: key); + final UnconfirmedPlayerModel player; // Неподтвержденный игрок + UnconfirmedPlayerView({Key? key, required this.player}) : super(key: key); @override Widget build(BuildContext context) { + MyTeamBloc bloc = context.watch(); return Container( child: Row( mainAxisAlignment: MainAxisAlignment.center, @@ -28,7 +31,8 @@ class PlayerToConfirm extends StatelessWidget { color: Colors.green, ), onPressed: () { - team.addWin(); + bloc.state.selectId = player.uid; + bloc.add(MyTeamEvent.confirmedPlayer); Fluttertoast.showToast( msg: '${player.name} добавлен в вашу команду', ); @@ -41,9 +45,8 @@ class PlayerToConfirm extends StatelessWidget { color: Colors.red, ), onPressed: () { - // context - // .read() - // .confirmPlayer(uid: player.uid, confirm: false); + bloc.state.selectId = player.uid; + bloc.add(MyTeamEvent.unconfirmedPlayer); Fluttertoast.showToast( msg: 'Заявка отклонена', ); diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 4d5894b..7b96d45 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -17,6 +17,17 @@ class Data with ChangeNotifier { }); } + void clearData() { + downloadSuccessful = false; + notifyListeners(); + DataService().initData().then((result) { + sortTour(); + sortData(); + downloadSuccessful = result; + notifyListeners(); + }); + } + static late CurrentTourData currentTour; static late List players; static late List teams; diff --git a/team_c_f/lib/models/currenttour.dart b/team_c_f/lib/models/currenttour.dart index 854915d..cb02cf6 100644 --- a/team_c_f/lib/models/currenttour.dart +++ b/team_c_f/lib/models/currenttour.dart @@ -1,4 +1,5 @@ class CurrentTourData { + late String docId; String round; CurrentTourData({required this.round}); @@ -8,7 +9,9 @@ class CurrentTourData { }; } - factory CurrentTourData.fromMap({required Map data}){ - return CurrentTourData(round: data['Round']); + factory CurrentTourData.fromMap({required Map data, required String docId}){ + CurrentTourData curr = CurrentTourData(round: data['Round']); + curr.docId = docId; + return curr; } } diff --git a/team_c_f/lib/models/player.dart b/team_c_f/lib/models/player.dart index 6d7dd82..2baaceb 100644 --- a/team_c_f/lib/models/player.dart +++ b/team_c_f/lib/models/player.dart @@ -34,13 +34,14 @@ class PlayerData { }; } - factory PlayerData.fromMap({required Map data}) { + factory PlayerData.fromMap({required Map data, required String docId}) { PlayerData p = PlayerData( name: data['Name'], team: data['Team'], uid: data['UserId'], ); p.points = [...data['Points']]; + p.docId = docId; return p; } } diff --git a/team_c_f/lib/models/team.dart b/team_c_f/lib/models/team.dart index 9b930df..23bc927 100644 --- a/team_c_f/lib/models/team.dart +++ b/team_c_f/lib/models/team.dart @@ -36,13 +36,14 @@ class TeamData { }; } - factory TeamData.fromMap({required Map data}) { + factory TeamData.fromMap({required Map data, required String docId}) { TeamData t = TeamData( name: data['Name'] as String, uidCapitan: data['Capitan'], ); t.players = [...data['Players']]; t.goal = [...data['Goal']]; + t.docId = docId; return t; } } diff --git a/team_c_f/lib/old/view/team.dart b/team_c_f/lib/old/view/team.dart index a8a77c2..cb5e789 100644 --- a/team_c_f/lib/old/view/team.dart +++ b/team_c_f/lib/old/view/team.dart @@ -84,7 +84,7 @@ class _TeamViewState extends State { ShowTeam( // Показ информации о моей команде team: context.read().myTeam!, - ) + ), ], ), ); diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index c63f91a..429c58c 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -1,9 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/pages/schedule.dart'; import 'package:team_c_f/pages/team.dart'; import 'package:team_c_f/servises/data.dart'; +import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:team_c_f/store/bloc/schedule.dart'; +import 'package:team_c_f/store/components/myteam.dart'; +import 'package:team_c_f/store/components/schedule.dart'; import 'package:team_c_f/store/home/home.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:bottom_navy_bar/bottom_navy_bar.dart'; @@ -14,66 +20,83 @@ class HomePage extends StatelessWidget { Widget build(BuildContext context) { return SafeArea( child: context.watch().downloadSuccessful - ? Scaffold( - body: Observer( - builder: (_) => Column( - children: [ - if (state.selectedIndex == 0) TeamPage(), - Data.tours.isNotEmpty - ? Text(Data.tours[0].round) - : Text('Туров нет'), - ElevatedButton( - onPressed: Provider.of(context).googleLogout, - child: Text( - '${state.selectedIndex}', + ? MultiBlocProvider( + providers: [ + BlocProvider( + create: (BuildContext context) => MyTeamBloc( + MyTeamState(uid: context.read().userId), + ), + ), + BlocProvider( + create: (BuildContext context) => ScheduleBloc( + ScheduleState(), + ), + ), + ], + child: Scaffold( + body: Observer( + builder: (_) => Column( + children: [ + if (state.selectedIndex == 0) + TeamPage() + else if (state.selectedIndex == 1) + SchedulePage(), + Data.tours.isNotEmpty + ? Text(Data.tours[0].round) + : Text('Туров нет'), + ElevatedButton( + onPressed: Provider.of(context).googleLogout, + child: Text( + '${state.selectedIndex}', + ), ), - ), - ], + ], + ), ), - ), - bottomNavigationBar: Observer( - builder: (_) => BottomNavyBar( - // Бар с вариантами выбора страниц - onItemSelected: state.selectIndex, - selectedIndex: state.selectedIndex, - iconSize: 20.0, - items: [ - BottomNavyBarItem( - icon: Icon(Icons.people), - title: Text( - 'Моя команда', - style: Theme.of(context).textTheme.caption, + bottomNavigationBar: Observer( + builder: (_) => BottomNavyBar( + // Бар с вариантами выбора страниц + onItemSelected: state.selectIndex, + selectedIndex: state.selectedIndex, + iconSize: 20.0, + items: [ + BottomNavyBarItem( + icon: Icon(Icons.people), + title: Text( + 'Моя команда', + style: Theme.of(context).textTheme.caption, + ), ), - ), - BottomNavyBarItem( - icon: Icon(Icons.calendar_today), - title: Text( - 'Календарь', - style: Theme.of(context).textTheme.caption, + BottomNavyBarItem( + icon: Icon(Icons.calendar_today), + title: Text( + 'Календарь', + style: Theme.of(context).textTheme.caption, + ), ), - ), - BottomNavyBarItem( - icon: Icon(Icons.add_to_photos), - title: Text( - 'Текущий тур', - style: Theme.of(context).textTheme.caption, + BottomNavyBarItem( + icon: Icon(Icons.add_to_photos), + title: Text( + 'Текущий тур', + style: Theme.of(context).textTheme.caption, + ), ), - ), - BottomNavyBarItem( - icon: Icon(Icons.toc), - title: Text( - 'Таблица', - style: Theme.of(context).textTheme.caption, + BottomNavyBarItem( + icon: Icon(Icons.toc), + title: Text( + 'Таблица', + style: Theme.of(context).textTheme.caption, + ), ), - ), - BottomNavyBarItem( - icon: Icon(Icons.list_alt), - title: Text( - 'Бомбардиры', - style: Theme.of(context).textTheme.caption, + BottomNavyBarItem( + icon: Icon(Icons.list_alt), + title: Text( + 'Бомбардиры', + style: Theme.of(context).textTheme.caption, + ), ), - ), - ], + ], + ), ), ), ) diff --git a/team_c_f/lib/pages/schedule.dart b/team_c_f/lib/pages/schedule.dart new file mode 100644 index 0000000..50ef070 --- /dev/null +++ b/team_c_f/lib/pages/schedule.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/components/createschedule.dart'; +import 'package:team_c_f/components/unconfirmedplayer.dart'; +import 'package:team_c_f/components/selectteam.dart'; +import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:team_c_f/store/bloc/schedule.dart'; +import 'package:team_c_f/store/components/myteam.dart'; +import 'package:team_c_f/store/components/schedule.dart'; +import 'package:team_c_f/store/login/login.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/views/team.dart'; + +class SchedulePage extends StatelessWidget { + @override + Widget build(BuildContext context) { + ScheduleBloc bloc = context.watch(); + // context.read().changeName(bloc.state.name); + // context.read().setDataToSelectTeam(buttonText: 'Выбрать команду'); + return BlocBuilder( + bloc: bloc, + builder: (context, state) => state.enableSchedule + ? Column( + children: [ + Text('Расписание'), + // Container( + // padding: const EdgeInsets.all(8.0), + // margin: const EdgeInsets.all(8.0), + // child: Column( + // children: [ + // Card( + // child: ListTile( + // leading: CircleAvatar( + // // Показывает место в таблице бомбардиров + // backgroundColor: Colors.blue[100], + // child: Text(bloc.state.position), + // ), + // title: Row( + // mainAxisSize: MainAxisSize.max, + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Text(bloc.state.name), // Показывает имя участника + // ], + // ), + // subtitle: bloc.state.team != 'Нет команды' + // ? Row( + // mainAxisSize: MainAxisSize.max, + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Icon(Icons.done, + // color: bloc.state.confirmed + // ? Colors.green + // : Colors.grey), + // Text(bloc.state.team), + // ], + // ) + // : Text( + // 'Нет команды', + // textAlign: TextAlign.center, + // ), + // trailing: CircleAvatar( + // backgroundColor: Colors.blue[100], + // child: IconButton( + // icon: Icon(Icons.exit_to_app), + // onPressed: () { + // context.read().googleLogout(); + // }), + // ), + // ), + // ), + // if (bloc.state.team == 'Нет команды') + // SelectTeamView( + // selectTeam: context.read().selectTeam, + // updateMyTeam: true, + // ), + // ], + // ), + // ), + // if (bloc.state.capitan && + // bloc.state.unconfirm + // .isNotEmpty) // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде + // ...bloc.state.unconfirm.map( + // (p) => PlayerToConfirm(player: p), + // ), + // if (bloc.state.teamData != null) + // ShowTeam( + // // Показ информации о моей команде + // team: bloc.state.teamData!, + // ), + ], + ) + : CreateScheduleView(), + ); + } +} diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index 564f25a..addc0be 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -1,61 +1,58 @@ import 'package:flutter/material.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:team_c_f/components/confirmedplayer.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/components/unconfirmedplayer.dart'; import 'package:team_c_f/components/selectteam.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:team_c_f/store/components/myteam.dart'; import 'package:team_c_f/store/login/login.dart'; -import 'package:team_c_f/store/myteam/myteam.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/views/team.dart'; class TeamPage extends StatelessWidget { @override Widget build(BuildContext context) { - MyTeam state = MyTeam( - player: Data.players - .where((PlayerData p) => p.uid == context.read().userId) - .single); - return Observer( - builder: (_) => state.team != null - ? Column( + MyTeamBloc bloc = context.watch(); + context.read().changeName(bloc.state.name); + context.read().setDataToSelectTeam(buttonText: 'Выбрать команду'); + return BlocBuilder( + bloc: bloc, + builder: (context, state) => Column( + children: [ + Container( + padding: const EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), + child: Column( children: [ Card( - color: Colors.red[100], - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100)), child: ListTile( leading: CircleAvatar( // Показывает место в таблице бомбардиров backgroundColor: Colors.blue[100], - child: Text(state.me.prevPosition.toString()), + child: Text(bloc.state.position), ), title: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text(state.me.name), // Показывает имя участника + Text(bloc.state.name), // Показывает имя участника ], ), - subtitle: state.me.team != null + subtitle: bloc.state.team != 'Нет команды' ? Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - // Показываем статус игрока, подтвержден ли он капитаном команды Icon(Icons.done, - color: state.team!.team.players - .where((String uid) => - uid == state.me.uid) - .length == - 1 + color: bloc.state.confirmed ? Colors.green : Colors.grey), - Text(state.me.team!), + Text(bloc.state.team), ], ) - : SelectTeamView( - selectTeam: context.read().selectTeam), + : Text( + 'Нет команды', + textAlign: TextAlign.center, + ), trailing: CircleAvatar( backgroundColor: Colors.blue[100], child: IconButton( @@ -66,28 +63,27 @@ class TeamPage extends StatelessWidget { ), ), ), - if (state.team != null) - if (state.team!.team.uidCapitan == state.me.uid) - // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде - Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - ...state.unconfirmPlayer.map( - (PlayerData p) => - PlayerToConfirm(player: p, team: state.team!), - ), - ], - ), - ), - if (state.team != null) - ShowTeam( - // Показ информации о моей команде - team: state.team!, + if (bloc.state.team == 'Нет команды') + SelectTeamView( + selectTeam: context.read().selectTeam, + updateMyTeam: true, ), ], - ) - : Text('Загрузка'), + ), + ), + if (bloc.state.capitan && + bloc.state.unconfirm + .isNotEmpty) // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде + ...bloc.state.unconfirm.map( + (p) => UnconfirmedPlayerView(player: p), + ), + if (bloc.state.teamData != null) + ShowTeam( + // Показ информации о моей команде + team: bloc.state.teamData!, + ), + ], + ), ); } } diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index 050549d..e0a012d 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -5,8 +5,7 @@ import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; -class DataService{ - +class DataService { final CollectionReference _playersCollection = FirebaseFirestore.instance.collection('players'); final CollectionReference _teamsCollection = @@ -30,6 +29,7 @@ class DataService{ return _currentTourCollection.get().then( (QuerySnapshot response) => CurrentTourData.fromMap( data: response.docs.single.data(), + docId: response.docs.single.id, ), ); } @@ -40,6 +40,7 @@ class DataService{ .map( (QueryDocumentSnapshot doc) => PlayerData.fromMap( data: doc.data(), + docId: doc.id, ), ) .toList(), @@ -52,6 +53,7 @@ class DataService{ .map( (QueryDocumentSnapshot doc) => TeamData.fromMap( data: doc.data(), + docId: doc.id, ), ) .toList(), diff --git a/team_c_f/lib/servises/myteam.dart b/team_c_f/lib/servises/myteam.dart index e9bc404..b3bdcb0 100644 --- a/team_c_f/lib/servises/myteam.dart +++ b/team_c_f/lib/servises/myteam.dart @@ -1,4 +1,5 @@ import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; @@ -8,11 +9,21 @@ class MyTeamService { final CollectionReference _teamsCollection = FirebaseFirestore.instance.collection('teams'); - void updatePlayer({required PlayerData player}) { - _playersCollection.doc(player.docId).update(player.toMap()); - } - - void updateTeam({required TeamData team}) { - _teamsCollection.doc(team.docId).update(team.toMap()); + void confirmedPlayer(bool confirmed, String uid) { + PlayerData player = + Data.players.where((PlayerData p) => p.uid == uid).single; + TeamData team = + Data.teams.where((TeamData t) => t.name == player.team).single; + if (confirmed) { + team.players.add(uid); + _teamsCollection.doc(team.docId).update(team.toMap()); + } else { + player.team = null; + _playersCollection.doc(player.docId).update(player.toMap()); + if (team.players.any((String playerUid) => playerUid == uid)) { + team.players.removeWhere((String playerId) => playerId == uid); + _teamsCollection.doc(team.docId).update(team.toMap()); + } + } } } diff --git a/team_c_f/lib/store/state.dart b/team_c_f/lib/servises/schedule.dart similarity index 100% rename from team_c_f/lib/store/state.dart rename to team_c_f/lib/servises/schedule.dart diff --git a/team_c_f/lib/servises/selectteam.dart b/team_c_f/lib/servises/selectteam.dart index 49bffe7..635c687 100644 --- a/team_c_f/lib/servises/selectteam.dart +++ b/team_c_f/lib/servises/selectteam.dart @@ -36,9 +36,16 @@ class SelectTeamService { return _teamsCollection.get().then( (QuerySnapshot response) => response.docs .where((QueryDocumentSnapshot doc) => - TeamData.fromMap(data: doc.data()).players.length < 3) + TeamData.fromMap( + data: doc.data(), + docId: doc.id, + ).players.length < + 3) .map( - (QueryDocumentSnapshot doc) => TeamData.fromMap(data: doc.data()).name, + (QueryDocumentSnapshot doc) => TeamData.fromMap( + data: doc.data(), + docId: doc.id, + ).name, ) .toList(), ); diff --git a/team_c_f/lib/servises/servises.dart b/team_c_f/lib/servises/servises.dart new file mode 100644 index 0000000..52c0a5b --- /dev/null +++ b/team_c_f/lib/servises/servises.dart @@ -0,0 +1,17 @@ +String showPoints(int points) { + // Функция изменения склонения слова "N очков" + return points.toString() + + ' ' + + ((points % 10 == 1 && points ~/ 10 != 1) + ? 'очко' + : ((points - 1) % 10 - 4 < 0 && points ~/ 10 != 1) + ? 'очка' + : 'очков'); +} + +String showGoals(int goals) { + // Функция изменения склонения слова "N забытых" + return goals.toString() + + ' ' + + ((goals % 10 == 1 && goals ~/ 10 != 1) ? 'забитый' : 'забитых'); +} diff --git a/team_c_f/lib/store/bloc/createschedule.dart b/team_c_f/lib/store/bloc/createschedule.dart new file mode 100644 index 0000000..e69de29 diff --git a/team_c_f/lib/store/bloc/myteam.dart b/team_c_f/lib/store/bloc/myteam.dart new file mode 100644 index 0000000..0a9228a --- /dev/null +++ b/team_c_f/lib/store/bloc/myteam.dart @@ -0,0 +1,33 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/servises/myteam.dart'; +import 'package:team_c_f/store/components/myteam.dart'; +import 'package:team_c_f/store/components/unconfirmedplayer.dart'; + +enum MyTeamEvent { confirmedPlayer, unconfirmedPlayer, reset } + +class MyTeamBloc extends Bloc { + MyTeamBloc(MyTeamState initialState) : super(initialState); + + @override + Stream mapEventToState(MyTeamEvent event) async* { + switch (event) { + case MyTeamEvent.confirmedPlayer: // текущий игрок одобрил заявку + MyTeamService().confirmedPlayer(true, state.selectId); + state.unconfirm.removeWhere( + (UnconfirmedPlayerModel player) => player.uid == state.selectId); + yield state.copyWith(unconfirm: state.unconfirm); + break; + case MyTeamEvent.unconfirmedPlayer: // текущий игрок не одобрил заявку + MyTeamService().confirmedPlayer(false, state.selectId); + if (state.unconfirm + .any((UnconfirmedPlayerModel player) => player.uid == state.selectId)) + state.unconfirm.removeWhere( + (UnconfirmedPlayerModel player) => player.uid == state.selectId); + yield state.copyWith(unconfirm: state.unconfirm); + break; + case MyTeamEvent.reset: + yield MyTeamState(uid: state.uid); + break; + } + } +} diff --git a/team_c_f/lib/store/bloc/schedule.dart b/team_c_f/lib/store/bloc/schedule.dart new file mode 100644 index 0000000..4d214ff --- /dev/null +++ b/team_c_f/lib/store/bloc/schedule.dart @@ -0,0 +1,40 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/servises/schedule.dart'; +import 'package:team_c_f/store/components/schedule.dart'; +import 'package:team_c_f/store/components/unconfirmedplayer.dart'; + +enum ScheduleEvent { + createSchedule +} //confirmedPlayer, unconfirmedPlayer, reset } + +class ScheduleBloc extends Bloc { + ScheduleBloc(ScheduleState initialState) : super(initialState); + + @override + Stream mapEventToState(ScheduleEvent event) async* { + switch (event) { + case ScheduleEvent.createSchedule: + yield state; + break; + + // switch (event) { + // case ScheduleEvent.confirmedPlayer: // текущий игрок одобрил заявку + // ScheduleService().confirmedPlayer(true, state.selectId); + // state.unconfirm.removeWhere( + // (UnconfirmedPlayerModel player) => player.uid == state.selectId); + // yield state.copyWith(unconfirm: state.unconfirm); + // break; + // case ScheduleEvent.unconfirmedPlayer: // текущий игрок не одобрил заявку + // ScheduleService().confirmedPlayer(false, state.selectId); + // if (state.unconfirm + // .any((UnconfirmedPlayerModel player) => player.uid == state.selectId)) + // state.unconfirm.removeWhere( + // (UnconfirmedPlayerModel player) => player.uid == state.selectId); + // yield state.copyWith(unconfirm: state.unconfirm); + // break; + // case ScheduleEvent.reset: + // yield ScheduleState(uid: state.uid); + // break; + } + } +} diff --git a/team_c_f/lib/store/components/myteam.dart b/team_c_f/lib/store/components/myteam.dart new file mode 100644 index 0000000..1d27251 --- /dev/null +++ b/team_c_f/lib/store/components/myteam.dart @@ -0,0 +1,81 @@ +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/store/components/team.dart'; +import 'package:team_c_f/store/components/unconfirmedplayer.dart'; + +class MyTeamState { + final String uid; + late String position; + late String name; + late String team = 'Нет команды'; + TeamModel? teamData; + late bool confirmed; + late bool capitan; + List unconfirm = []; + late String selectId; + + MyTeamState({required this.uid}) { + PlayerData p = Data.players + .where((PlayerData playerData) => playerData.uid == uid) + .single; + position = p.prevPosition.toString(); + name = p.name; + if (p.team != null) { + team = p.team!; + TeamData t = + Data.teams.where((TeamData teamData) => teamData.name == team).single; + teamData = TeamModel(team: t); + confirmed = t.players.any((String uid) => uid == this.uid); + capitan = t.uidCapitan == uid; + + if (capitan) { + unconfirm = [ + ...Data.players + .where((PlayerData playerData) => playerData.team == team) + .where((PlayerData playerData) => + t.players.every((String uid) => uid != playerData.uid)) + .map((PlayerData playerData) => + UnconfirmedPlayerModel(uid: playerData.uid)) + ]; + } + } else { + capitan = false; + confirmed = false; + } + } + + MyTeamState copyWith({ + String? position, + bool? confirmed, + String? team, + TeamModel? teamData, + bool? capitan, + List? unconfirm, + }) => + MyTeamState.all( + uid: uid, + position: position ?? this.position, + confirmed: confirmed ?? this.confirmed, + name: name, + team: team == null + ? this.team + : team == '' + ? 'Нет команды' + : team, + teamData: teamData ?? this.teamData, + capitan: capitan ?? this.capitan, + unconfirm: unconfirm ?? this.unconfirm, + ); + + MyTeamState.all({ + required this.uid, + required this.position, + required this.confirmed, + required this.name, + required this.team, + required this.teamData, + required this.capitan, + required this.unconfirm, + }); +} diff --git a/team_c_f/lib/store/components/schedule.dart b/team_c_f/lib/store/components/schedule.dart new file mode 100644 index 0000000..01aefef --- /dev/null +++ b/team_c_f/lib/store/components/schedule.dart @@ -0,0 +1,20 @@ +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/store/components/tour.dart'; + +class ScheduleState { + late bool enableSchedule; + late List tours = []; + + ScheduleState() { + tours = [...Data.tours.map((TourData tour) => TourModel(tour: tour))]; + enableSchedule = tours.isNotEmpty; + } + + ScheduleState copyWith({ + List? tours, + }) => + ScheduleState.all(tours: tours ?? this.tours); + + ScheduleState.all({required this.tours}); +} diff --git a/team_c_f/lib/store/components/team.dart b/team_c_f/lib/store/components/team.dart new file mode 100644 index 0000000..2cf5a6a --- /dev/null +++ b/team_c_f/lib/store/components/team.dart @@ -0,0 +1,14 @@ +import 'package:team_c_f/models/team.dart'; + +class TeamModel{ + final TeamData team; + late String teamName; + late String position; + late int points; + + TeamModel({required this.team}){ + teamName = team.name; + position = team.prevPosition.toString(); + points = team.points; + } +} \ No newline at end of file diff --git a/team_c_f/lib/store/components/tour.dart b/team_c_f/lib/store/components/tour.dart new file mode 100644 index 0000000..2c64075 --- /dev/null +++ b/team_c_f/lib/store/components/tour.dart @@ -0,0 +1,11 @@ +import 'package:team_c_f/models/tour.dart'; + +class TourModel{ + late String name; + final TourData tour; + + + TourModel({required this.tour}){ + name = tour.name ?? tour.round; + } +} \ No newline at end of file diff --git a/team_c_f/lib/store/components/unconfirmedplayer.dart b/team_c_f/lib/store/components/unconfirmedplayer.dart new file mode 100644 index 0000000..7ab8e1c --- /dev/null +++ b/team_c_f/lib/store/components/unconfirmedplayer.dart @@ -0,0 +1,10 @@ +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/player.dart'; + +class UnconfirmedPlayerModel { + final String uid; + late String name; + UnconfirmedPlayerModel({required this.uid}) { + name = Data.players.where((PlayerData p) => p.uid == uid).single.name; + } +} diff --git a/team_c_f/lib/store/login/login.dart b/team_c_f/lib/store/login/login.dart index 8f924fe..d227d66 100644 --- a/team_c_f/lib/store/login/login.dart +++ b/team_c_f/lib/store/login/login.dart @@ -21,7 +21,7 @@ abstract class LoginBase with Store { InfoData? info; @action - void initInfo(){ + void initInfo() { LoginService().getInfo().then((InfoData value) => info = value); } @@ -85,12 +85,13 @@ abstract class LoginBase with Store { loginStatus = ObservableFuture.value(false); userId = ''; registrateInApp = false; + clearData(); return await Future.value(true); } @action Future validateInApp() async { - registrateInApp = await LoginService().existPlayer(uid: userId); + registrateInApp = await LoginService().existPlayer(uid: userId); } Future getGoogleUser() async { @@ -105,7 +106,7 @@ abstract class LoginBase with Store { } @action - void clearData(){ + void clearData() { userName = ''; selectTeam.lastTeamName = ''; selectTeam.teamName = ''; diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index 1d12db3..64a8d64 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -1,4 +1,5 @@ import 'package:mobx/mobx.dart'; +import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/servises/selectteam.dart'; import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/player.dart'; @@ -70,6 +71,7 @@ abstract class _SelectTeamBase with Store { uid: uId, docId: docId, ); + Data().clearData(); return docId == null ? await SelectTeamService().registratePlayer( player: p, diff --git a/team_c_f/lib/views/player.dart b/team_c_f/lib/views/player.dart index 4f435c5..b6c7cc6 100644 --- a/team_c_f/lib/views/player.dart +++ b/team_c_f/lib/views/player.dart @@ -1,6 +1,9 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter/material.dart'; import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/servises/servises.dart'; +import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:provider/provider.dart'; class ShowPlayer extends StatelessWidget { // Класс отображающий информацию об указанном игроке @@ -9,29 +12,31 @@ class ShowPlayer extends StatelessWidget { @override Widget build(BuildContext context) { + MyTeamBloc bloc = context.watch(); return Container( child: InkWell( onLongPress: () async { - // if (context.read().me.capitan && - // (await showAlertDialog( - // context: context, - // title: 'Изменение состава', - // message: 'Удалить ${player.name}', - // actions: [ - // AlertDialogAction( - // key: true, - // label: 'Да, удалить', - // isDefaultAction: true, - // ), - // AlertDialogAction( - // key: false, - // label: 'Отмена', - // isDestructiveAction: true, - // ), - // ], - // ))!) { - // context.read().removePlayerFromMyTeam(uid: player.uid); - // } + if (bloc.state.capitan && + (await showAlertDialog( + context: context, + title: 'Изменение состава', + message: 'Удалить ${player.name}', + actions: [ + AlertDialogAction( + key: true, + label: 'Да, удалить', + isDefaultAction: true, + ), + AlertDialogAction( + key: false, + label: 'Отмена', + isDestructiveAction: true, + ), + ], + ))!) { + bloc.state.selectId = player.uid; + bloc.add(MyTeamEvent.unconfirmedPlayer); + } }, child: Card( child: ListTile( @@ -39,8 +44,9 @@ class ShowPlayer extends StatelessWidget { child: Text(player.prevPosition.toString()), ), title: Text(player.name), - trailing: Text(player.goals.toString()), - //showPoints(player.points)), + trailing: Text( + showGoals(player.goals), + ), ), ), ), diff --git a/team_c_f/lib/views/team.dart b/team_c_f/lib/views/team.dart index 82c29bc..4ec56ac 100644 --- a/team_c_f/lib/views/team.dart +++ b/team_c_f/lib/views/team.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/store/team/team.dart'; +import 'package:team_c_f/servises/servises.dart'; +import 'package:team_c_f/store/components/team.dart'; import 'package:team_c_f/views/player.dart'; class ShowTeam extends StatelessWidget { // Класс отображения информации об указанной команде - final Team team; // Команда + final TeamModel team; // Команда ShowTeam({Key? key, required this.team}) : super(key: key); @override @@ -24,8 +25,8 @@ class ShowTeam extends StatelessWidget { ), ), title: Text(team.team.name), - trailing: Text(team.team.points.toString() - //showPoints(team.points), + trailing: Text(//team.team.points.toString() + showPoints(team.points), ), ), ), diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index e2716ba..81746ef 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -43,6 +43,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.5.0" + bloc: + dependency: transitive + description: + name: bloc + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.0" boolean_selector: dependency: transitive description: @@ -314,6 +321,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.0" flutter_mobx: dependency: "direct main" description: @@ -555,13 +569,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.1" - redux: - dependency: "direct main" - description: - name: redux - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.0" shelf: dependency: transitive description: diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index 0ee0eac..d858c7d 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -32,7 +32,7 @@ dependencies: http: ^0.13.1 html: ^0.15.0 carousel_slider: ^3.0.0 - redux: ^5.0.0 + flutter_bloc: ^7.0.0 custom_navigation_bar: ^0.8.1 bottom_navy_bar: ^6.0.0 From 14e30adf91b1a94f2a995a188e725607df15a0b3 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 10 May 2021 17:25:50 +0300 Subject: [PATCH 16/24] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=80=D0=B0=D1=81=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/pages/schedule.dart | 76 +++++--------------------------- 1 file changed, 10 insertions(+), 66 deletions(-) diff --git a/team_c_f/lib/pages/schedule.dart b/team_c_f/lib/pages/schedule.dart index 50ef070..f68e0d0 100644 --- a/team_c_f/lib/pages/schedule.dart +++ b/team_c_f/lib/pages/schedule.dart @@ -3,8 +3,12 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/components/createschedule.dart'; import 'package:team_c_f/components/unconfirmedplayer.dart'; import 'package:team_c_f/components/selectteam.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/store/bloc/createschedule.dart'; import 'package:team_c_f/store/bloc/myteam.dart'; import 'package:team_c_f/store/bloc/schedule.dart'; +import 'package:team_c_f/store/components/createschedule.dart'; import 'package:team_c_f/store/components/myteam.dart'; import 'package:team_c_f/store/components/schedule.dart'; import 'package:team_c_f/store/login/login.dart'; @@ -22,74 +26,14 @@ class SchedulePage extends StatelessWidget { builder: (context, state) => state.enableSchedule ? Column( children: [ - Text('Расписание'), - // Container( - // padding: const EdgeInsets.all(8.0), - // margin: const EdgeInsets.all(8.0), - // child: Column( - // children: [ - // Card( - // child: ListTile( - // leading: CircleAvatar( - // // Показывает место в таблице бомбардиров - // backgroundColor: Colors.blue[100], - // child: Text(bloc.state.position), - // ), - // title: Row( - // mainAxisSize: MainAxisSize.max, - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // Text(bloc.state.name), // Показывает имя участника - // ], - // ), - // subtitle: bloc.state.team != 'Нет команды' - // ? Row( - // mainAxisSize: MainAxisSize.max, - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // Icon(Icons.done, - // color: bloc.state.confirmed - // ? Colors.green - // : Colors.grey), - // Text(bloc.state.team), - // ], - // ) - // : Text( - // 'Нет команды', - // textAlign: TextAlign.center, - // ), - // trailing: CircleAvatar( - // backgroundColor: Colors.blue[100], - // child: IconButton( - // icon: Icon(Icons.exit_to_app), - // onPressed: () { - // context.read().googleLogout(); - // }), - // ), - // ), - // ), - // if (bloc.state.team == 'Нет команды') - // SelectTeamView( - // selectTeam: context.read().selectTeam, - // updateMyTeam: true, - // ), - // ], - // ), - // ), - // if (bloc.state.capitan && - // bloc.state.unconfirm - // .isNotEmpty) // Отображение для капитана списка игроков, которые зарегистрировались, но ещё не получили подтверждение в его команде - // ...bloc.state.unconfirm.map( - // (p) => PlayerToConfirm(player: p), - // ), - // if (bloc.state.teamData != null) - // ShowTeam( - // // Показ информации о моей команде - // team: bloc.state.teamData!, - // ), + ...Data.tours.map((TourData tour) => ) ], ) - : CreateScheduleView(), + : BlocProvider( + create: (context) => CreateScheduleBloc( + CreateScheduleState(), + ), + child: CreateScheduleView()), ); } } From a78ce043ed06df7ca5453f72a10f15e4f3272963 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 11 May 2021 00:11:51 +0300 Subject: [PATCH 17/24] =?UTF-8?q?=D0=9E=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D1=8B=20=D1=82=D1=83=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/createschedule.dart | 70 ++++++++++++- team_c_f/lib/components/selectteam.dart | 2 +- .../lib/components/unconfirmedplayer.dart | 7 +- team_c_f/lib/data/data.dart | 97 ++++++------------- team_c_f/lib/models/meet.dart | 35 +++++++ team_c_f/lib/models/tour.dart | 16 ++- team_c_f/lib/pages/home.dart | 41 ++++---- team_c_f/lib/pages/schedule.dart | 37 ++++--- team_c_f/lib/pages/team.dart | 4 +- team_c_f/lib/servises/createschedule.dart | 19 ++++ team_c_f/lib/servises/data.dart | 2 +- team_c_f/lib/servises/schedule.dart | 17 ++++ team_c_f/lib/servises/servises.dart | 94 ++++++++++++++++++ team_c_f/lib/store/bloc/createschedule.dart | 0 team_c_f/lib/store/components/schedule.dart | 20 ---- team_c_f/lib/store/components/tour.dart | 11 --- team_c_f/lib/store/myteam/myteam.dart | 43 -------- team_c_f/lib/store/myteam/myteam.g.dart | 78 --------------- team_c_f/lib/store/team/team.dart | 30 ------ team_c_f/lib/store/team/team.g.dart | 49 ---------- .../lib/storebloc/blocs/createschedule.dart | 27 ++++++ .../bloc => storebloc/blocs}/myteam.dart | 4 +- .../bloc => storebloc/blocs}/schedule.dart | 19 ++-- .../storebloc/components/createschedule.dart | 34 +++++++ .../components/myteam.dart | 4 +- .../lib/storebloc/components/schedule.dart | 32 ++++++ team_c_f/lib/storebloc/models/meet.dart | 15 +++ .../components => storebloc/models}/team.dart | 0 team_c_f/lib/storebloc/models/tour.dart | 28 ++++++ .../models}/unconfirmedplayer.dart | 0 team_c_f/lib/views/player.dart | 2 +- team_c_f/lib/views/team.dart | 2 +- team_c_f/lib/views/tour.dart | 21 ++++ 33 files changed, 499 insertions(+), 361 deletions(-) create mode 100644 team_c_f/lib/models/meet.dart create mode 100644 team_c_f/lib/servises/createschedule.dart delete mode 100644 team_c_f/lib/store/bloc/createschedule.dart delete mode 100644 team_c_f/lib/store/components/schedule.dart delete mode 100644 team_c_f/lib/store/components/tour.dart delete mode 100644 team_c_f/lib/store/myteam/myteam.dart delete mode 100644 team_c_f/lib/store/myteam/myteam.g.dart delete mode 100644 team_c_f/lib/store/team/team.dart delete mode 100644 team_c_f/lib/store/team/team.g.dart create mode 100644 team_c_f/lib/storebloc/blocs/createschedule.dart rename team_c_f/lib/{store/bloc => storebloc/blocs}/myteam.dart (91%) rename team_c_f/lib/{store/bloc => storebloc/blocs}/schedule.dart (75%) create mode 100644 team_c_f/lib/storebloc/components/createschedule.dart rename team_c_f/lib/{store => storebloc}/components/myteam.dart (94%) create mode 100644 team_c_f/lib/storebloc/components/schedule.dart create mode 100644 team_c_f/lib/storebloc/models/meet.dart rename team_c_f/lib/{store/components => storebloc/models}/team.dart (100%) create mode 100644 team_c_f/lib/storebloc/models/tour.dart rename team_c_f/lib/{store/components => storebloc/models}/unconfirmedplayer.dart (100%) create mode 100644 team_c_f/lib/views/tour.dart diff --git a/team_c_f/lib/components/createschedule.dart b/team_c_f/lib/components/createschedule.dart index 49c97bc..f42ddff 100644 --- a/team_c_f/lib/components/createschedule.dart +++ b/team_c_f/lib/components/createschedule.dart @@ -1,12 +1,78 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:team_c_f/servises/servises.dart'; +import 'package:team_c_f/storebloc/blocs/createschedule.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart'; class CreateScheduleView extends StatelessWidget { const CreateScheduleView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { + CreateScheduleBloc bloc = context.watch(); return Container( - child: Text('Нет расписания'), + child: Card( + child: ListTile( + title: Container( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text( + showRegisterTeam(bloc.state.registTeam) + + ' ' + + showTeam(bloc.state.registTeam), + ), + SizedBox(height: 20), + Text( + showFullTeam(bloc.state.fullTeam) + + ' ' + + showTeam(bloc.state.fullTeam), + ), + SizedBox(height: 20), + Text('Укажите количество кругов в чемпионате'), + TextField( + textAlign: TextAlign.center, + keyboardType: TextInputType.number, + onChanged: (circle) { + circle.trim(); + bloc.state.circle = circle != '' ? int.parse(circle) : 1; + bloc.add(CreateScheduleEvent.changeCircle); + }, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + ], + ), + SizedBox(height: 20), + Text( + 'Ожидается ' + + showMatches( + matches: bloc.state.matches, + ) + + ' в каждом туре', + ), + SizedBox(height: 20), + Text( + 'Ожидается ' + + showTours( + tours: bloc.state.tours, + ), + ), + SizedBox(height: 20), + ElevatedButton( + onPressed: () { + bloc.add(CreateScheduleEvent.createSchedule); + context.read().add(ScheduleEvent.createSuccessful); + }, + child: Text( + 'Создать расписание', + ), + ), + ], + ), + ), + ), + ), ); } -} \ No newline at end of file +} diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index 751a7e7..b8673c6 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:team_c_f/storebloc/blocs/myteam.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/store/selectteam/selectteam.dart'; diff --git a/team_c_f/lib/components/unconfirmedplayer.dart b/team_c_f/lib/components/unconfirmedplayer.dart index 345937f..01767c8 100644 --- a/team_c_f/lib/components/unconfirmedplayer.dart +++ b/team_c_f/lib/components/unconfirmedplayer.dart @@ -1,11 +1,8 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/player.dart'; -import 'package:team_c_f/store/bloc/myteam.dart'; -import 'package:team_c_f/store/components/unconfirmedplayer.dart'; +import 'package:team_c_f/storebloc/blocs/myteam.dart'; +import 'package:team_c_f/storebloc/models/unconfirmedplayer.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/store/team/team.dart'; class UnconfirmedPlayerView extends StatelessWidget { // Класс, для отображения неподтвержденных игроков diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 7b96d45..5f03a72 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; import 'package:team_c_f/models/currenttour.dart'; +import 'package:team_c_f/models/meet.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/servises/data.dart'; +import 'package:team_c_f/servises/schedule.dart'; class Data with ChangeNotifier { bool downloadSuccessful = false; @@ -35,7 +37,7 @@ class Data with ChangeNotifier { static void sortTour() { tours.sort((TourData a, b) => - a.round.compareTo(b.round)); // сортировка туров по порядку + int.parse(a.round).compareTo(int.parse(b.round))); // сортировка туров по порядку } static void sortData() { @@ -56,31 +58,33 @@ class Data with ChangeNotifier { teams.where((TeamData team) => team.name == pair[0]).single; TeamData away = teams.where((TeamData team) => team.name == pair[1]).single; - if (home.goal[round] == null && away.goal[round] == null) { - home.lose++; - away.lose++; - } else if (home.goal[round] == null) { - home.lose++; - away.win++; - home.missed += away.goal[round]!; - } else if (away.goal[round] == null) { - away.lose++; - home.win++; - away.missed += home.goal[round]!; - } else { - int goalHome = home.goal[round]!; - int goalAway = away.goal[round]!; - home.missed += goalAway; - away.missed += goalHome; - if (goalHome > goalAway) { - home.win++; + if (home.goal.length > round) { + if (home.goal[round] == null && away.goal[round] == null) { + home.lose++; away.lose++; - } else if (goalAway > goalHome) { - away.win++; + } else if (home.goal[round] == null) { home.lose++; + away.win++; + home.missed += away.goal[round]!; + } else if (away.goal[round] == null) { + away.lose++; + home.win++; + away.missed += home.goal[round]!; } else { - home.draw++; - away.draw++; + int goalHome = home.goal[round]!; + int goalAway = away.goal[round]!; + home.missed += goalAway; + away.missed += goalHome; + if (goalHome > goalAway) { + home.win++; + away.lose++; + } else if (goalAway > goalHome) { + away.win++; + home.lose++; + } else { + home.draw++; + away.draw++; + } } } }, @@ -101,49 +105,8 @@ class Data with ChangeNotifier { }, ); // указание текущей позиции команды } - // static void initTeams({required List data}){ - // data.sort((TeamData a, b) => a.points.compareTo(b.points)); - // } - - // Текущий тур (подписка) - // { - // *получаемые поля - // номер тура (строка). - // } - // Игроки - // { - // *получаемые поля - // идентификатор (строка), - // имя (строка), - // название команды (строка), - // лист забитых за тур (лист интов, null при пропуске тура). - // *вычисляемые поля - // максимум забитых за тур (инт), - // количество забитых за все матчи (инт), - // позиция (инт). - // } - // Команды - // { - // *получаемые поля - // название (строка), - // идентификатор капитана (строка) - // лист участников (лист строк с идентификаторами). - - // *вычисляемые поля - // максимум забитых за тур (инт) - // количество забитых за все матчи (инт), - // количество пропущенных за все матчи (инт), - // победы (инт), - // ничьи (инт), - // поражения (инт), - // очки (инт), - // позиция (инт). - // } - // Туры - // { - // *получаемые поля - // номер тура (строка), - // лист участников (лист типа: команда, забитые). - // } + static Future getMeets(String stage) async { + return ScheduleService().getMeets(stage: stage); + } } diff --git a/team_c_f/lib/models/meet.dart b/team_c_f/lib/models/meet.dart new file mode 100644 index 0000000..5ebcfa7 --- /dev/null +++ b/team_c_f/lib/models/meet.dart @@ -0,0 +1,35 @@ +class MeetData { + final String round; + final List team; + final DateTime date; + final List score; + final bool started; + + MeetData({ + required this.round, + required this.team, + required this.date, + required this.score, + required this.started, + }); + + factory MeetData.fromMap({required Map data}) { + return MeetData( + round: data['Round'], + team: data['Team'], + date: data['Date'], + score: data['Score'], + started: data['Started'], + ); + } + + Map toMap() { + return { + 'Round': round, + 'Team': team, + 'Date': date, + 'Score': score, + 'Started': started, + }; + } +} diff --git a/team_c_f/lib/models/tour.dart b/team_c_f/lib/models/tour.dart index cf0420c..e2e2448 100644 --- a/team_c_f/lib/models/tour.dart +++ b/team_c_f/lib/models/tour.dart @@ -1,20 +1,28 @@ class TourData { final String round; String? name; - late List> team; // проверить порядок + late List> team; TourData({required this.round, this.name}); + String get stage => name?? round; + + TourData.all({ + required this.round, + required this.team, + }); + Map toMap() { return { 'Round': round, - 'Team': team, - 'Name': name == null ? round : name, + 'Team': team.map((List match) => match.first + '><' + match.last).toList(), + 'Name': name ?? round, }; } factory TourData.fromMap({required Map data}) { TourData t = TourData(round: data['Round'], name: data['Name']); - t.team = data['Team']; + List match = data['Team'].cast(); + t.team = match.map((String pair) => pair.split('><').toList()).toList(); return t; } } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index 429c58c..c0b63d4 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -5,11 +5,10 @@ import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/pages/schedule.dart'; import 'package:team_c_f/pages/team.dart'; -import 'package:team_c_f/servises/data.dart'; -import 'package:team_c_f/store/bloc/myteam.dart'; -import 'package:team_c_f/store/bloc/schedule.dart'; -import 'package:team_c_f/store/components/myteam.dart'; -import 'package:team_c_f/store/components/schedule.dart'; +import 'package:team_c_f/storebloc/blocs/myteam.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart'; +import 'package:team_c_f/storebloc/components/myteam.dart'; +import 'package:team_c_f/storebloc/components/schedule.dart'; import 'package:team_c_f/store/home/home.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:bottom_navy_bar/bottom_navy_bar.dart'; @@ -35,22 +34,24 @@ class HomePage extends StatelessWidget { ], child: Scaffold( body: Observer( - builder: (_) => Column( - children: [ - if (state.selectedIndex == 0) - TeamPage() - else if (state.selectedIndex == 1) - SchedulePage(), - Data.tours.isNotEmpty - ? Text(Data.tours[0].round) - : Text('Туров нет'), - ElevatedButton( - onPressed: Provider.of(context).googleLogout, - child: Text( - '${state.selectedIndex}', + builder: (_) => SingleChildScrollView( + child: Column( + children: [ + if (state.selectedIndex == 0) + TeamPage() + else if (state.selectedIndex == 1) + SchedulePage(), + Data.tours.isNotEmpty + ? Text(Data.tours[0].round) + : Text('Туров нет'), + ElevatedButton( + onPressed: Provider.of(context).googleLogout, + child: Text( + '${state.selectedIndex}', + ), ), - ), - ], + ], + ), ), ), bottomNavigationBar: Observer( diff --git a/team_c_f/lib/pages/schedule.dart b/team_c_f/lib/pages/schedule.dart index f68e0d0..39381c5 100644 --- a/team_c_f/lib/pages/schedule.dart +++ b/team_c_f/lib/pages/schedule.dart @@ -1,33 +1,38 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/components/createschedule.dart'; -import 'package:team_c_f/components/unconfirmedplayer.dart'; -import 'package:team_c_f/components/selectteam.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/tour.dart'; -import 'package:team_c_f/store/bloc/createschedule.dart'; -import 'package:team_c_f/store/bloc/myteam.dart'; -import 'package:team_c_f/store/bloc/schedule.dart'; -import 'package:team_c_f/store/components/createschedule.dart'; -import 'package:team_c_f/store/components/myteam.dart'; -import 'package:team_c_f/store/components/schedule.dart'; -import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/storebloc/blocs/createschedule.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart'; +import 'package:team_c_f/storebloc/components/createschedule.dart'; +import 'package:team_c_f/storebloc/components/schedule.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/views/team.dart'; +import 'package:team_c_f/storebloc/models/tour.dart'; +import 'package:team_c_f/views/tour.dart'; class SchedulePage extends StatelessWidget { @override Widget build(BuildContext context) { ScheduleBloc bloc = context.watch(); - // context.read().changeName(bloc.state.name); - // context.read().setDataToSelectTeam(buttonText: 'Выбрать команду'); return BlocBuilder( bloc: bloc, builder: (context, state) => state.enableSchedule - ? Column( - children: [ - ...Data.tours.map((TourData tour) => ) - ], + ? Container( + height: MediaQuery.of(context).size.height, + width: double.infinity, + color: Colors.amber, + child: Wrap( + alignment: WrapAlignment.spaceAround, + runAlignment: WrapAlignment.center, + spacing: 20, + runSpacing: 20, + children: [ + ...bloc.state.tours.map( + (TourModel tour) => ShowTour(tour: tour), + ), + ], + ), ) : BlocProvider( create: (context) => CreateScheduleBloc( diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index addc0be..b301b43 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/components/unconfirmedplayer.dart'; import 'package:team_c_f/components/selectteam.dart'; -import 'package:team_c_f/store/bloc/myteam.dart'; -import 'package:team_c_f/store/components/myteam.dart'; +import 'package:team_c_f/storebloc/blocs/myteam.dart'; +import 'package:team_c_f/storebloc/components/myteam.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/views/team.dart'; diff --git a/team_c_f/lib/servises/createschedule.dart b/team_c_f/lib/servises/createschedule.dart new file mode 100644 index 0000000..6c7699e --- /dev/null +++ b/team_c_f/lib/servises/createschedule.dart @@ -0,0 +1,19 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/tour.dart'; + +class CreateScheduleService { + final CollectionReference _scheduleCollection = + FirebaseFirestore.instance.collection('schedule'); + + void create() { + Map a = Data.tours.first.toMap(); + Data.tours.forEach( + (TourData tour) { + _scheduleCollection.add( + tour.toMap(), + ); + }, + ); + } +} diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index e0a012d..f790ed5 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -13,7 +13,7 @@ class DataService { final CollectionReference _currentTourCollection = FirebaseFirestore.instance.collection('currentTour'); final CollectionReference _toursCollection = - FirebaseFirestore.instance.collection('tours'); + FirebaseFirestore.instance.collection('schedule'); // final CollectionReference _forecastsCollection = // FirebaseFirestore.instance.collection('forecasts'); diff --git a/team_c_f/lib/servises/schedule.dart b/team_c_f/lib/servises/schedule.dart index e69de29..9963e9d 100644 --- a/team_c_f/lib/servises/schedule.dart +++ b/team_c_f/lib/servises/schedule.dart @@ -0,0 +1,17 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/tour.dart'; + +class ScheduleService { + final CollectionReference _meetsCollection = + FirebaseFirestore.instance.collection('meets'); + + Future getMeets({required String stage}) { + return _meetsCollection.where('Round', isEqualTo: stage).get().then( + (QuerySnapshot response) => MeetData.fromMap( + data: response.docs.single.data(), + ), + ); + } +} diff --git a/team_c_f/lib/servises/servises.dart b/team_c_f/lib/servises/servises.dart index 52c0a5b..977bed2 100644 --- a/team_c_f/lib/servises/servises.dart +++ b/team_c_f/lib/servises/servises.dart @@ -1,3 +1,7 @@ +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/models/tour.dart'; + String showPoints(int points) { // Функция изменения склонения слова "N очков" return points.toString() + @@ -15,3 +19,93 @@ String showGoals(int goals) { ' ' + ((goals % 10 == 1 && goals ~/ 10 != 1) ? 'забитый' : 'забитых'); } + +String showRegisterTeam(int count) { + // Функция изменения склонения слова "Зарегистрировано" + return (count % 10 == 1 && count ~/ 10 != 1) + ? 'Зарегистрирована' + : 'Зарегистрировано'; +} + +String showFullTeam(int count) { + // Функция изменения склонения выражения "Готово к участию" + return (count % 10 == 1 && count ~/ 10 != 1) + ? 'Готова к участию' + : 'Готово к участию'; +} + +String showTeam(int points) { + // Функция изменения склонения слова "N команд" + return points.toString() + + ' ' + + ((points % 10 == 1 && points ~/ 10 != 1) + ? 'команда' + : ((points - 1) % 10 - 4 < 0 && points ~/ 10 != 1) + ? 'команды' + : 'команд'); +} + +String showMatches({required int matches}) { + return matches.toString() + + ' ' + + ((matches % 10 == 1 && matches ~/ 10 != 1) + ? 'матч' + : ((matches - 1) % 10 - 4 < 0 && matches ~/ 10 != 1) + ? 'матча' + : 'матчей'); +} + +String showTours({required int tours}) { + return tours.toString() + + ' ' + + ((tours % 10 == 1 && tours ~/ 10 != 1) + ? 'тур' + : ((tours - 1) % 10 - 4 < 0 && tours ~/ 10 != 1) + ? 'тура' + : 'туров'); +} + +List createSchedule(int circles) { + List registTeam = + Data.teams.where((TeamData team) => team.players.length == 3).toList(); + List teams =['1', '2', '3', '4', '5']; + // registTeam + // .map((TeamData team) => team.name) + // .toList(); //['1', '2', '3', '4', '5']; + List curr = []; + int count = 5;//registTeam.length; + int tour = (count.isEven ? count - 1 : count); + for (int q = 0; q < circles; q++) { + for (int i = 0; i < tour; i++) { + List> pair = []; + for (int j = 0; j < count ~/ 2; j++) { + List match = []; + int k = count.isEven ? j : j + 1; + int home = i.isOdd + ? k == 0 + ? count - 1 + : (count ~/ 2 + i ~/ 2 + k + (count.isEven ? 0 : 1)) % + (count.isOdd ? count : count - 1) + : k + i ~/ 2; + int away = i.isOdd + ? count ~/ 2 + i ~/ 2 - j + : k == 0 + ? count - 1 + : (count + i ~/ 2 - 1 - k + (count.isEven ? 0 : 1)) % + (count.isOdd ? count : count - 1); + if (q.isEven) { + match.add(teams[home]); + match.add(teams[away]); + } else { + match.add(teams[away]); + match.add(teams[home]); + } + pair.add(match); + } + curr.add( + TourData.all(round: (i + 1 + q * tour).toString(), team: pair), + ); + } + } + return [...curr]; +} diff --git a/team_c_f/lib/store/bloc/createschedule.dart b/team_c_f/lib/store/bloc/createschedule.dart deleted file mode 100644 index e69de29..0000000 diff --git a/team_c_f/lib/store/components/schedule.dart b/team_c_f/lib/store/components/schedule.dart deleted file mode 100644 index 01aefef..0000000 --- a/team_c_f/lib/store/components/schedule.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/tour.dart'; -import 'package:team_c_f/store/components/tour.dart'; - -class ScheduleState { - late bool enableSchedule; - late List tours = []; - - ScheduleState() { - tours = [...Data.tours.map((TourData tour) => TourModel(tour: tour))]; - enableSchedule = tours.isNotEmpty; - } - - ScheduleState copyWith({ - List? tours, - }) => - ScheduleState.all(tours: tours ?? this.tours); - - ScheduleState.all({required this.tours}); -} diff --git a/team_c_f/lib/store/components/tour.dart b/team_c_f/lib/store/components/tour.dart deleted file mode 100644 index 2c64075..0000000 --- a/team_c_f/lib/store/components/tour.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:team_c_f/models/tour.dart'; - -class TourModel{ - late String name; - final TourData tour; - - - TourModel({required this.tour}){ - name = tour.name ?? tour.round; - } -} \ No newline at end of file diff --git a/team_c_f/lib/store/myteam/myteam.dart b/team_c_f/lib/store/myteam/myteam.dart deleted file mode 100644 index 21cdbf7..0000000 --- a/team_c_f/lib/store/myteam/myteam.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:mobx/mobx.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/player.dart'; -import 'package:team_c_f/store/team/team.dart'; -part 'myteam.g.dart'; - -class MyTeam extends _MyTeamBase with _$MyTeam { - MyTeam({required PlayerData player}) : super(me: player); -} - -abstract class _MyTeamBase with Store { - _MyTeamBase({required this.me}) { - team = Team( - team: Data.teams.where((element) => element.name == me.team).single); - if (me.uid == team!.team.uidCapitan) { - List inTeam = []; - inTeam.addAll( - Data.players.where((PlayerData p) => p.team == team!.team.name), - ); - unconfirmPlayer.addAll( - inTeam.where( - (PlayerData p) => - team!.team.players.every((String uid) => uid != p.uid), - ), - ); - } - } - - @observable - List unconfirmPlayer = []; - - @action - void confirm({required String uid, required bool confirm}) { - unconfirmPlayer.removeWhere((PlayerData p) => p.uid == uid); - if (confirm) team!.team.players.add(uid); - } - - @observable - PlayerData me; - - @observable - Team? team; -} diff --git a/team_c_f/lib/store/myteam/myteam.g.dart b/team_c_f/lib/store/myteam/myteam.g.dart deleted file mode 100644 index e18002d..0000000 --- a/team_c_f/lib/store/myteam/myteam.g.dart +++ /dev/null @@ -1,78 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'myteam.dart'; - -// ************************************************************************** -// StoreGenerator -// ************************************************************************** - -// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic - -mixin _$MyTeam on _MyTeamBase, Store { - final _$unconfirmPlayerAtom = Atom(name: '_MyTeamBase.unconfirmPlayer'); - - @override - List get unconfirmPlayer { - _$unconfirmPlayerAtom.reportRead(); - return super.unconfirmPlayer; - } - - @override - set unconfirmPlayer(List value) { - _$unconfirmPlayerAtom.reportWrite(value, super.unconfirmPlayer, () { - super.unconfirmPlayer = value; - }); - } - - final _$meAtom = Atom(name: '_MyTeamBase.me'); - - @override - PlayerData get me { - _$meAtom.reportRead(); - return super.me; - } - - @override - set me(PlayerData value) { - _$meAtom.reportWrite(value, super.me, () { - super.me = value; - }); - } - - final _$teamAtom = Atom(name: '_MyTeamBase.team'); - - @override - Team? get team { - _$teamAtom.reportRead(); - return super.team; - } - - @override - set team(Team? value) { - _$teamAtom.reportWrite(value, super.team, () { - super.team = value; - }); - } - - final _$_MyTeamBaseActionController = ActionController(name: '_MyTeamBase'); - - @override - void confirm({required String uid, required bool confirm}) { - final _$actionInfo = - _$_MyTeamBaseActionController.startAction(name: '_MyTeamBase.confirm'); - try { - return super.confirm(uid: uid, confirm: confirm); - } finally { - _$_MyTeamBaseActionController.endAction(_$actionInfo); - } - } - - @override - String toString() { - return ''' -unconfirmPlayer: ${unconfirmPlayer}, -me: ${me}, -team: ${team} - '''; - } -} diff --git a/team_c_f/lib/store/team/team.dart b/team_c_f/lib/store/team/team.dart deleted file mode 100644 index 1060683..0000000 --- a/team_c_f/lib/store/team/team.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:mobx/mobx.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/player.dart'; -import 'package:team_c_f/models/team.dart'; -part 'team.g.dart'; - -class Team extends _TeamBase with _$Team { - Team({required TeamData team}) : super(team: team); -} - -abstract class _TeamBase with Store { - _TeamBase({required this.team}) { - team.players.forEach( - (String uid) { - players.add(Data.players.where((PlayerData p) => p.uid == uid).single); - }, - ); - } - - @observable - List players = []; - - @observable - late TeamData team; - - @action - void addWin(){ - team.win++; - } -} diff --git a/team_c_f/lib/store/team/team.g.dart b/team_c_f/lib/store/team/team.g.dart deleted file mode 100644 index 2d9a6db..0000000 --- a/team_c_f/lib/store/team/team.g.dart +++ /dev/null @@ -1,49 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'team.dart'; - -// ************************************************************************** -// StoreGenerator -// ************************************************************************** - -// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic - -mixin _$Team on _TeamBase, Store { - final _$playersAtom = Atom(name: '_TeamBase.players'); - - @override - List get players { - _$playersAtom.reportRead(); - return super.players; - } - - @override - set players(List value) { - _$playersAtom.reportWrite(value, super.players, () { - super.players = value; - }); - } - - final _$teamAtom = Atom(name: '_TeamBase.team'); - - @override - TeamData get team { - _$teamAtom.reportRead(); - return super.team; - } - - @override - set team(TeamData value) { - _$teamAtom.reportWrite(value, super.team, () { - super.team = value; - }); - } - - @override - String toString() { - return ''' -players: ${players}, -team: ${team} - '''; - } -} diff --git a/team_c_f/lib/storebloc/blocs/createschedule.dart b/team_c_f/lib/storebloc/blocs/createschedule.dart new file mode 100644 index 0000000..e06d09a --- /dev/null +++ b/team_c_f/lib/storebloc/blocs/createschedule.dart @@ -0,0 +1,27 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/servises/createschedule.dart'; +import 'package:team_c_f/servises/servises.dart'; +import 'package:team_c_f/storebloc/components/createschedule.dart'; + +enum CreateScheduleEvent { changeCircle, createSchedule } + +class CreateScheduleBloc + extends Bloc { + CreateScheduleBloc(CreateScheduleState initialState) : super(initialState); + + @override + Stream mapEventToState( + CreateScheduleEvent event) async* { + switch (event) { + case CreateScheduleEvent.changeCircle: + yield state.copyWith(circle: state.circle); + break; + case CreateScheduleEvent.createSchedule: + Data.tours = createSchedule(state.circle); + CreateScheduleService().create(); + yield state; + break; + } + } +} diff --git a/team_c_f/lib/store/bloc/myteam.dart b/team_c_f/lib/storebloc/blocs/myteam.dart similarity index 91% rename from team_c_f/lib/store/bloc/myteam.dart rename to team_c_f/lib/storebloc/blocs/myteam.dart index 0a9228a..6b79ddd 100644 --- a/team_c_f/lib/store/bloc/myteam.dart +++ b/team_c_f/lib/storebloc/blocs/myteam.dart @@ -1,7 +1,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/servises/myteam.dart'; -import 'package:team_c_f/store/components/myteam.dart'; -import 'package:team_c_f/store/components/unconfirmedplayer.dart'; +import 'package:team_c_f/storebloc/components/myteam.dart'; +import 'package:team_c_f/storebloc/models/unconfirmedplayer.dart'; enum MyTeamEvent { confirmedPlayer, unconfirmedPlayer, reset } diff --git a/team_c_f/lib/store/bloc/schedule.dart b/team_c_f/lib/storebloc/blocs/schedule.dart similarity index 75% rename from team_c_f/lib/store/bloc/schedule.dart rename to team_c_f/lib/storebloc/blocs/schedule.dart index 4d214ff..39df56d 100644 --- a/team_c_f/lib/store/bloc/schedule.dart +++ b/team_c_f/lib/storebloc/blocs/schedule.dart @@ -1,10 +1,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:team_c_f/servises/schedule.dart'; -import 'package:team_c_f/store/components/schedule.dart'; -import 'package:team_c_f/store/components/unconfirmedplayer.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/storebloc/components/schedule.dart'; +import 'package:team_c_f/storebloc/models/tour.dart'; enum ScheduleEvent { - createSchedule + createSuccessful } //confirmedPlayer, unconfirmedPlayer, reset } class ScheduleBloc extends Bloc { @@ -13,8 +14,14 @@ class ScheduleBloc extends Bloc { @override Stream mapEventToState(ScheduleEvent event) async* { switch (event) { - case ScheduleEvent.createSchedule: - yield state; + case ScheduleEvent.createSuccessful: + yield state.copyWith( + tours: Data.tours + .map( + (TourData tour) => TourModel(tour: tour), + ) + .toList(), + ); break; // switch (event) { diff --git a/team_c_f/lib/storebloc/components/createschedule.dart b/team_c_f/lib/storebloc/components/createschedule.dart new file mode 100644 index 0000000..24b1f6c --- /dev/null +++ b/team_c_f/lib/storebloc/components/createschedule.dart @@ -0,0 +1,34 @@ +import 'dart:core'; +import 'package:team_c_f/data/data.dart'; + +class CreateScheduleState { + late int circle; + late int registTeam; + late int fullTeam; + int get matches => (fullTeam / 2).floor(); + int get tours => circle * (fullTeam.isEven ? fullTeam - 1 : fullTeam); + + CreateScheduleState() { + circle = 1; + registTeam = Data.teams.length; + fullTeam = 16; + //Data.teams.where((TeamData team) => team.players.length == 3).length; + } + + CreateScheduleState copyWith({ + int? circle, + int? registTeam, + int? fullTeam, + }) => + CreateScheduleState.all( + circle: circle ?? this.circle, + registTeam: registTeam ?? this.registTeam, + fullTeam: fullTeam ?? this.fullTeam, + ); + + CreateScheduleState.all({ + required this.circle, + required this.registTeam, + required this.fullTeam, + }); +} diff --git a/team_c_f/lib/store/components/myteam.dart b/team_c_f/lib/storebloc/components/myteam.dart similarity index 94% rename from team_c_f/lib/store/components/myteam.dart rename to team_c_f/lib/storebloc/components/myteam.dart index 1d27251..2a98239 100644 --- a/team_c_f/lib/store/components/myteam.dart +++ b/team_c_f/lib/storebloc/components/myteam.dart @@ -1,8 +1,8 @@ import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; -import 'package:team_c_f/store/components/team.dart'; -import 'package:team_c_f/store/components/unconfirmedplayer.dart'; +import 'package:team_c_f/storebloc/models/team.dart'; +import 'package:team_c_f/storebloc/models/unconfirmedplayer.dart'; class MyTeamState { final String uid; diff --git a/team_c_f/lib/storebloc/components/schedule.dart b/team_c_f/lib/storebloc/components/schedule.dart new file mode 100644 index 0000000..dd19f26 --- /dev/null +++ b/team_c_f/lib/storebloc/components/schedule.dart @@ -0,0 +1,32 @@ +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/storebloc/models/tour.dart'; +import 'package:team_c_f/storebloc/models/meet.dart'; + +class ScheduleState { + bool get enableSchedule => Data.tours.isNotEmpty; + late List tours = []; + late MeetModel meets; + + ScheduleState() { + tours = [...Data.tours.map((TourData tour) => TourModel(tour: tour))]; + Data.getMeets(Data.currentTour.round).then( + (MeetData meet) => meets = MeetModel(meet: meet), + ); + } + + ScheduleState copyWith({ + List? tours, + MeetModel? meets, + }) => + ScheduleState.all( + tours: tours ?? this.tours, + meets: meets ?? this.meets, + ); + + ScheduleState.all({ + required this.tours, + required this.meets, + }); +} diff --git a/team_c_f/lib/storebloc/models/meet.dart b/team_c_f/lib/storebloc/models/meet.dart new file mode 100644 index 0000000..f0c5188 --- /dev/null +++ b/team_c_f/lib/storebloc/models/meet.dart @@ -0,0 +1,15 @@ +import 'package:team_c_f/models/meet.dart'; + +class MeetModel { + late List team = []; + late List score = []; + late String info; + late bool started; + + MeetModel({required MeetData meet}) { + team = meet.team; + score = meet.score; + info = meet.date.toString(); + started = meet.started; + } +} diff --git a/team_c_f/lib/store/components/team.dart b/team_c_f/lib/storebloc/models/team.dart similarity index 100% rename from team_c_f/lib/store/components/team.dart rename to team_c_f/lib/storebloc/models/team.dart diff --git a/team_c_f/lib/storebloc/models/tour.dart b/team_c_f/lib/storebloc/models/tour.dart new file mode 100644 index 0000000..9176131 --- /dev/null +++ b/team_c_f/lib/storebloc/models/tour.dart @@ -0,0 +1,28 @@ +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/team.dart'; +import 'package:team_c_f/models/tour.dart'; + +class TourModel { + late String name; + late List>> result; + late List> matches; + late List> goals; + + TourModel({required TourData tour}) { + name = tour.name ?? tour.round; + int round = int.parse(tour.round) - 1; + result = tour.team.map( + (List pair) { + return pair.map( + (String team) { + TeamData teamData = + Data.teams.where((TeamData t) => t.name == team).single; + return { + team: teamData.goal.length > round ? teamData.goal[round] : null + }; + }, + ).toList(); + }, + ).toList(); + } +} diff --git a/team_c_f/lib/store/components/unconfirmedplayer.dart b/team_c_f/lib/storebloc/models/unconfirmedplayer.dart similarity index 100% rename from team_c_f/lib/store/components/unconfirmedplayer.dart rename to team_c_f/lib/storebloc/models/unconfirmedplayer.dart diff --git a/team_c_f/lib/views/player.dart b/team_c_f/lib/views/player.dart index b6c7cc6..5f7bdc2 100644 --- a/team_c_f/lib/views/player.dart +++ b/team_c_f/lib/views/player.dart @@ -2,7 +2,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter/material.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/servises/servises.dart'; -import 'package:team_c_f/store/bloc/myteam.dart'; +import 'package:team_c_f/storebloc/blocs/myteam.dart'; import 'package:provider/provider.dart'; class ShowPlayer extends StatelessWidget { diff --git a/team_c_f/lib/views/team.dart b/team_c_f/lib/views/team.dart index 4ec56ac..6e007b3 100644 --- a/team_c_f/lib/views/team.dart +++ b/team_c_f/lib/views/team.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/servises/servises.dart'; -import 'package:team_c_f/store/components/team.dart'; +import 'package:team_c_f/storebloc/models/team.dart'; import 'package:team_c_f/views/player.dart'; class ShowTeam extends StatelessWidget { diff --git a/team_c_f/lib/views/tour.dart b/team_c_f/lib/views/tour.dart new file mode 100644 index 0000000..979d30a --- /dev/null +++ b/team_c_f/lib/views/tour.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/storebloc/models/tour.dart'; + +class ShowTour extends StatelessWidget { + final TourModel tour; + const ShowTour({Key? key, required this.tour}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(3.0), + child: CircleAvatar( + radius: MediaQuery.of(context).size.width / 10, + child: Text( + tour.name, + maxLines: 3, + style: TextStyle(fontSize: MediaQuery.of(context).size.width / 15), + )), + ); + } +} From 37ab4ac94202165668a90009ee28d455b317c9bb Mon Sep 17 00:00:00 2001 From: Dmitry Date: Tue, 11 May 2021 21:40:33 +0300 Subject: [PATCH 18/24] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B8=D0=B4=D0=B0=20=D1=82?= =?UTF-8?q?=D1=83=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/createschedule.dart | 4 +- team_c_f/lib/data/data.dart | 2 +- team_c_f/lib/models/tour.dart | 6 +-- team_c_f/lib/pages/home.dart | 25 +++++----- team_c_f/lib/pages/schedule.dart | 46 +++++++++--------- team_c_f/lib/pages/team.dart | 2 +- team_c_f/lib/pages/tour.dart | 28 +++++++++++ team_c_f/lib/servises/servises.dart | 2 +- team_c_f/lib/store/home/home.dart | 2 +- .../lib/storebloc/blocs/createschedule.dart | 2 +- team_c_f/lib/storebloc/blocs/myteam.dart | 2 +- team_c_f/lib/storebloc/blocs/schedule.dart | 48 +++++++++---------- team_c_f/lib/storebloc/blocs/tour.dart | 40 ++++++++++++++++ team_c_f/lib/storebloc/models/tour.dart | 4 +- .../createschedule.dart | 0 .../{components => states}/myteam.dart | 0 .../{components => states}/schedule.dart | 12 ++++- team_c_f/lib/storebloc/states/tour.dart | 18 +++++++ team_c_f/lib/views/tour.dart | 24 +++++++--- 19 files changed, 187 insertions(+), 80 deletions(-) create mode 100644 team_c_f/lib/pages/tour.dart create mode 100644 team_c_f/lib/storebloc/blocs/tour.dart rename team_c_f/lib/storebloc/{components => states}/createschedule.dart (100%) rename team_c_f/lib/storebloc/{components => states}/myteam.dart (100%) rename team_c_f/lib/storebloc/{components => states}/schedule.dart (72%) create mode 100644 team_c_f/lib/storebloc/states/tour.dart diff --git a/team_c_f/lib/components/createschedule.dart b/team_c_f/lib/components/createschedule.dart index f42ddff..8cf12c8 100644 --- a/team_c_f/lib/components/createschedule.dart +++ b/team_c_f/lib/components/createschedule.dart @@ -62,7 +62,9 @@ class CreateScheduleView extends StatelessWidget { ElevatedButton( onPressed: () { bloc.add(CreateScheduleEvent.createSchedule); - context.read().add(ScheduleEvent.createSuccessful); + context + .read() + .add(ScheduleEvent(event: Event.createSuccessful)); }, child: Text( 'Создать расписание', diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 5f03a72..3cbc7ef 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -37,7 +37,7 @@ class Data with ChangeNotifier { static void sortTour() { tours.sort((TourData a, b) => - int.parse(a.round).compareTo(int.parse(b.round))); // сортировка туров по порядку + a.round.compareTo(b.round)); // сортировка туров по порядку } static void sortData() { diff --git a/team_c_f/lib/models/tour.dart b/team_c_f/lib/models/tour.dart index e2e2448..e7648c2 100644 --- a/team_c_f/lib/models/tour.dart +++ b/team_c_f/lib/models/tour.dart @@ -1,10 +1,10 @@ class TourData { - final String round; + final int round; String? name; late List> team; TourData({required this.round, this.name}); - String get stage => name?? round; + String get stage => name?? round.toString(); TourData.all({ required this.round, @@ -15,7 +15,7 @@ class TourData { return { 'Round': round, 'Team': team.map((List match) => match.first + '><' + match.last).toList(), - 'Name': name ?? round, + 'Name': name ?? round.toString(), }; } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index c0b63d4..71a3123 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -5,13 +5,16 @@ import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/pages/schedule.dart'; import 'package:team_c_f/pages/team.dart'; +import 'package:team_c_f/pages/tour.dart'; import 'package:team_c_f/storebloc/blocs/myteam.dart'; import 'package:team_c_f/storebloc/blocs/schedule.dart'; -import 'package:team_c_f/storebloc/components/myteam.dart'; -import 'package:team_c_f/storebloc/components/schedule.dart'; +import 'package:team_c_f/storebloc/blocs/tour.dart'; +import 'package:team_c_f/storebloc/states/myteam.dart'; +import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:team_c_f/store/home/home.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:bottom_navy_bar/bottom_navy_bar.dart'; +import 'package:team_c_f/storebloc/states/tour.dart'; class HomePage extends StatelessWidget { static Home state = Home(); @@ -31,6 +34,11 @@ class HomePage extends StatelessWidget { ScheduleState(), ), ), + BlocProvider( + create: (BuildContext context) => TourBloc( + TourState(name: Data.currentTour.round), + ), + ), ], child: Scaffold( body: Observer( @@ -40,16 +48,9 @@ class HomePage extends StatelessWidget { if (state.selectedIndex == 0) TeamPage() else if (state.selectedIndex == 1) - SchedulePage(), - Data.tours.isNotEmpty - ? Text(Data.tours[0].round) - : Text('Туров нет'), - ElevatedButton( - onPressed: Provider.of(context).googleLogout, - child: Text( - '${state.selectedIndex}', - ), - ), + SchedulePage() + else if (state.selectedIndex == 2) + TourPage(back: false) ], ), ), diff --git a/team_c_f/lib/pages/schedule.dart b/team_c_f/lib/pages/schedule.dart index 39381c5..b5e6830 100644 --- a/team_c_f/lib/pages/schedule.dart +++ b/team_c_f/lib/pages/schedule.dart @@ -1,12 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/components/createschedule.dart'; -import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/pages/tour.dart'; import 'package:team_c_f/storebloc/blocs/createschedule.dart'; import 'package:team_c_f/storebloc/blocs/schedule.dart'; -import 'package:team_c_f/storebloc/components/createschedule.dart'; -import 'package:team_c_f/storebloc/components/schedule.dart'; +import 'package:team_c_f/storebloc/states/createschedule.dart'; +import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:team_c_f/views/tour.dart'; @@ -18,27 +17,30 @@ class SchedulePage extends StatelessWidget { return BlocBuilder( bloc: bloc, builder: (context, state) => state.enableSchedule - ? Container( - height: MediaQuery.of(context).size.height, - width: double.infinity, - color: Colors.amber, - child: Wrap( - alignment: WrapAlignment.spaceAround, - runAlignment: WrapAlignment.center, - spacing: 20, - runSpacing: 20, - children: [ - ...bloc.state.tours.map( - (TourModel tour) => ShowTour(tour: tour), + ? state.tourSelected + ? TourPage(back: true) + : Container( + height: MediaQuery.of(context).size.height, + width: double.infinity, + color: Colors.amber, + child: Wrap( + alignment: WrapAlignment.spaceAround, + runAlignment: WrapAlignment.center, + spacing: 20, + runSpacing: 20, + children: [ + ...bloc.state.tours.map( + (TourModel tour) => ShowTour(tour: tour), + ), + ], ), - ], - ), - ) + ) : BlocProvider( create: (context) => CreateScheduleBloc( - CreateScheduleState(), - ), - child: CreateScheduleView()), + CreateScheduleState(), + ), + child: CreateScheduleView(), + ), ); } } diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index b301b43..bc55987 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/components/unconfirmedplayer.dart'; import 'package:team_c_f/components/selectteam.dart'; import 'package:team_c_f/storebloc/blocs/myteam.dart'; -import 'package:team_c_f/storebloc/components/myteam.dart'; +import 'package:team_c_f/storebloc/states/myteam.dart'; import 'package:team_c_f/store/login/login.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/views/team.dart'; diff --git a/team_c_f/lib/pages/tour.dart b/team_c_f/lib/pages/tour.dart new file mode 100644 index 0000000..58848cc --- /dev/null +++ b/team_c_f/lib/pages/tour.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart'; + +class TourPage extends StatelessWidget { + final bool back; + const TourPage({Key? key, required this.back}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + if (back) + TextButton( + onPressed: () { + context.read().add( + ScheduleEvent(event: Event.unselectTour), + ); + }, + child: Text('Назад'), + ), + Container( + child: Text('Show tour'), + ), + ], + ); + } +} diff --git a/team_c_f/lib/servises/servises.dart b/team_c_f/lib/servises/servises.dart index 977bed2..da3e03c 100644 --- a/team_c_f/lib/servises/servises.dart +++ b/team_c_f/lib/servises/servises.dart @@ -103,7 +103,7 @@ List createSchedule(int circles) { pair.add(match); } curr.add( - TourData.all(round: (i + 1 + q * tour).toString(), team: pair), + TourData.all(round: (i + 1 + q * tour), team: pair), ); } } diff --git a/team_c_f/lib/store/home/home.dart b/team_c_f/lib/store/home/home.dart index 23f3460..a696e07 100644 --- a/team_c_f/lib/store/home/home.dart +++ b/team_c_f/lib/store/home/home.dart @@ -5,7 +5,7 @@ class Home = _HomeBase with _$Home; abstract class _HomeBase with Store { @observable - int selectedIndex = 0; + int selectedIndex = 1; @action void selectIndex(int index){ diff --git a/team_c_f/lib/storebloc/blocs/createschedule.dart b/team_c_f/lib/storebloc/blocs/createschedule.dart index e06d09a..8d993af 100644 --- a/team_c_f/lib/storebloc/blocs/createschedule.dart +++ b/team_c_f/lib/storebloc/blocs/createschedule.dart @@ -2,7 +2,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/servises/createschedule.dart'; import 'package:team_c_f/servises/servises.dart'; -import 'package:team_c_f/storebloc/components/createschedule.dart'; +import 'package:team_c_f/storebloc/states/createschedule.dart'; enum CreateScheduleEvent { changeCircle, createSchedule } diff --git a/team_c_f/lib/storebloc/blocs/myteam.dart b/team_c_f/lib/storebloc/blocs/myteam.dart index 6b79ddd..7847ec4 100644 --- a/team_c_f/lib/storebloc/blocs/myteam.dart +++ b/team_c_f/lib/storebloc/blocs/myteam.dart @@ -1,6 +1,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/servises/myteam.dart'; -import 'package:team_c_f/storebloc/components/myteam.dart'; +import 'package:team_c_f/storebloc/states/myteam.dart'; import 'package:team_c_f/storebloc/models/unconfirmedplayer.dart'; enum MyTeamEvent { confirmedPlayer, unconfirmedPlayer, reset } diff --git a/team_c_f/lib/storebloc/blocs/schedule.dart b/team_c_f/lib/storebloc/blocs/schedule.dart index 39df56d..6e0846d 100644 --- a/team_c_f/lib/storebloc/blocs/schedule.dart +++ b/team_c_f/lib/storebloc/blocs/schedule.dart @@ -1,20 +1,29 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/tour.dart'; -import 'package:team_c_f/storebloc/components/schedule.dart'; +import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; -enum ScheduleEvent { - createSuccessful -} //confirmedPlayer, unconfirmedPlayer, reset } +class ScheduleEvent { + final String? stage; + final Event event; + + ScheduleEvent({this.stage, required this.event}); +} + +enum Event { + createSuccessful, + selectTour, + unselectTour, +} class ScheduleBloc extends Bloc { ScheduleBloc(ScheduleState initialState) : super(initialState); @override Stream mapEventToState(ScheduleEvent event) async* { - switch (event) { - case ScheduleEvent.createSuccessful: + switch (event.event) { + case Event.createSuccessful: yield state.copyWith( tours: Data.tours .map( @@ -23,25 +32,14 @@ class ScheduleBloc extends Bloc { .toList(), ); break; - - // switch (event) { - // case ScheduleEvent.confirmedPlayer: // текущий игрок одобрил заявку - // ScheduleService().confirmedPlayer(true, state.selectId); - // state.unconfirm.removeWhere( - // (UnconfirmedPlayerModel player) => player.uid == state.selectId); - // yield state.copyWith(unconfirm: state.unconfirm); - // break; - // case ScheduleEvent.unconfirmedPlayer: // текущий игрок не одобрил заявку - // ScheduleService().confirmedPlayer(false, state.selectId); - // if (state.unconfirm - // .any((UnconfirmedPlayerModel player) => player.uid == state.selectId)) - // state.unconfirm.removeWhere( - // (UnconfirmedPlayerModel player) => player.uid == state.selectId); - // yield state.copyWith(unconfirm: state.unconfirm); - // break; - // case ScheduleEvent.reset: - // yield ScheduleState(uid: state.uid); - // break; + case Event.selectTour: + if (event.stage != null) { + yield state.copyWith(nameTour: event.stage, tourSelected: true); + } + break; + case Event.unselectTour: + yield state.copyWith(tourSelected: false); + break; } } } diff --git a/team_c_f/lib/storebloc/blocs/tour.dart b/team_c_f/lib/storebloc/blocs/tour.dart new file mode 100644 index 0000000..0dbd2bc --- /dev/null +++ b/team_c_f/lib/storebloc/blocs/tour.dart @@ -0,0 +1,40 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/storebloc/states/schedule.dart'; +import 'package:team_c_f/storebloc/models/tour.dart'; +import 'package:team_c_f/storebloc/states/tour.dart'; + +class TourEvent { + String? stage; + final Event event; + + TourEvent({this.stage, required this.event}); +} + +enum Event { + makeForecast, + selectMeets, + selectTour, +} + +class TourBloc extends Bloc { + TourBloc(TourState initialState) : super(initialState); + + @override + Stream mapEventToState(TourEvent event) async* { + switch (event.event) { + case Event.makeForecast: + yield state; + break; + case Event.selectMeets: + yield state; + break; + case Event.selectTour: + if (event.stage != null) { + yield state; + } + break; + } + } +} diff --git a/team_c_f/lib/storebloc/models/tour.dart b/team_c_f/lib/storebloc/models/tour.dart index 9176131..3e1614f 100644 --- a/team_c_f/lib/storebloc/models/tour.dart +++ b/team_c_f/lib/storebloc/models/tour.dart @@ -9,8 +9,8 @@ class TourModel { late List> goals; TourModel({required TourData tour}) { - name = tour.name ?? tour.round; - int round = int.parse(tour.round) - 1; + name = tour.name ?? tour.round.toString(); + int round = tour.round - 1; result = tour.team.map( (List pair) { return pair.map( diff --git a/team_c_f/lib/storebloc/components/createschedule.dart b/team_c_f/lib/storebloc/states/createschedule.dart similarity index 100% rename from team_c_f/lib/storebloc/components/createschedule.dart rename to team_c_f/lib/storebloc/states/createschedule.dart diff --git a/team_c_f/lib/storebloc/components/myteam.dart b/team_c_f/lib/storebloc/states/myteam.dart similarity index 100% rename from team_c_f/lib/storebloc/components/myteam.dart rename to team_c_f/lib/storebloc/states/myteam.dart diff --git a/team_c_f/lib/storebloc/components/schedule.dart b/team_c_f/lib/storebloc/states/schedule.dart similarity index 72% rename from team_c_f/lib/storebloc/components/schedule.dart rename to team_c_f/lib/storebloc/states/schedule.dart index dd19f26..cc74a06 100644 --- a/team_c_f/lib/storebloc/components/schedule.dart +++ b/team_c_f/lib/storebloc/states/schedule.dart @@ -6,8 +6,10 @@ import 'package:team_c_f/storebloc/models/meet.dart'; class ScheduleState { bool get enableSchedule => Data.tours.isNotEmpty; + late bool tourSelected = false; + late String nameTour; late List tours = []; - late MeetModel meets; + MeetModel? meets; ScheduleState() { tours = [...Data.tours.map((TourData tour) => TourModel(tour: tour))]; @@ -19,14 +21,20 @@ class ScheduleState { ScheduleState copyWith({ List? tours, MeetModel? meets, + String? nameTour, + bool? tourSelected, }) => ScheduleState.all( tours: tours ?? this.tours, meets: meets ?? this.meets, + nameTour: nameTour ?? this.nameTour, + tourSelected: tourSelected ?? this.tourSelected, ); ScheduleState.all({ required this.tours, - required this.meets, + this.meets, + required this.nameTour, + required this.tourSelected, }); } diff --git a/team_c_f/lib/storebloc/states/tour.dart b/team_c_f/lib/storebloc/states/tour.dart new file mode 100644 index 0000000..1b634a7 --- /dev/null +++ b/team_c_f/lib/storebloc/states/tour.dart @@ -0,0 +1,18 @@ +import 'package:team_c_f/data/data.dart'; + +class TourState { + final String name; // цифровой + + TourState({required this.name}); + + TourState copyWith({ + String? name, + }) => + TourState.all( + name: name ?? this.name, + ); + + TourState.all({ + required this.name + }); +} diff --git a/team_c_f/lib/views/tour.dart b/team_c_f/lib/views/tour.dart index 979d30a..ee437bc 100644 --- a/team_c_f/lib/views/tour.dart +++ b/team_c_f/lib/views/tour.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; +import 'package:provider/provider.dart'; class ShowTour extends StatelessWidget { final TourModel tour; @@ -9,13 +11,21 @@ class ShowTour extends StatelessWidget { Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(3.0), - child: CircleAvatar( - radius: MediaQuery.of(context).size.width / 10, - child: Text( - tour.name, - maxLines: 3, - style: TextStyle(fontSize: MediaQuery.of(context).size.width / 15), - )), + child: InkWell( + onTap: () { + context.read().add( + ScheduleEvent(event: Event.selectTour, stage: tour.name), + ); + }, + child: CircleAvatar( + radius: MediaQuery.of(context).size.width / 10, + child: Text( + tour.name, + maxLines: 3, + style: + TextStyle(fontSize: MediaQuery.of(context).size.width / 15), + )), + ), ); } } From 0513cba88af6b4c34fb70053032867f2a2b14ca5 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 12 May 2021 13:04:48 +0300 Subject: [PATCH 19/24] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=B2=D0=B8=D0=B4=20=D0=B4=D0=BB=D1=8F=20=D0=BD?= =?UTF-8?q?=D0=B5=D1=86=D0=B8=D1=84=D1=80=D0=BE=D0=B2=D1=8B=D1=85=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B9=20=D1=82=D1=83=D1=80?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/models/currenttour.dart | 2 +- team_c_f/lib/storebloc/states/schedule.dart | 7 ------- team_c_f/lib/storebloc/states/tour.dart | 4 ++-- team_c_f/lib/views/tour.dart | 18 ++++++++++++++---- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/team_c_f/lib/models/currenttour.dart b/team_c_f/lib/models/currenttour.dart index cb02cf6..585fba4 100644 --- a/team_c_f/lib/models/currenttour.dart +++ b/team_c_f/lib/models/currenttour.dart @@ -1,6 +1,6 @@ class CurrentTourData { late String docId; - String round; + int round; CurrentTourData({required this.round}); Map toMap() { diff --git a/team_c_f/lib/storebloc/states/schedule.dart b/team_c_f/lib/storebloc/states/schedule.dart index cc74a06..ad181b7 100644 --- a/team_c_f/lib/storebloc/states/schedule.dart +++ b/team_c_f/lib/storebloc/states/schedule.dart @@ -1,5 +1,4 @@ import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/meet.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:team_c_f/storebloc/models/meet.dart'; @@ -9,13 +8,9 @@ class ScheduleState { late bool tourSelected = false; late String nameTour; late List tours = []; - MeetModel? meets; ScheduleState() { tours = [...Data.tours.map((TourData tour) => TourModel(tour: tour))]; - Data.getMeets(Data.currentTour.round).then( - (MeetData meet) => meets = MeetModel(meet: meet), - ); } ScheduleState copyWith({ @@ -26,14 +21,12 @@ class ScheduleState { }) => ScheduleState.all( tours: tours ?? this.tours, - meets: meets ?? this.meets, nameTour: nameTour ?? this.nameTour, tourSelected: tourSelected ?? this.tourSelected, ); ScheduleState.all({ required this.tours, - this.meets, required this.nameTour, required this.tourSelected, }); diff --git a/team_c_f/lib/storebloc/states/tour.dart b/team_c_f/lib/storebloc/states/tour.dart index 1b634a7..dab1872 100644 --- a/team_c_f/lib/storebloc/states/tour.dart +++ b/team_c_f/lib/storebloc/states/tour.dart @@ -1,12 +1,12 @@ import 'package:team_c_f/data/data.dart'; class TourState { - final String name; // цифровой + final int name; // цифровой TourState({required this.name}); TourState copyWith({ - String? name, + int? name, }) => TourState.all( name: name ?? this.name, diff --git a/team_c_f/lib/views/tour.dart b/team_c_f/lib/views/tour.dart index ee437bc..3d2522a 100644 --- a/team_c_f/lib/views/tour.dart +++ b/team_c_f/lib/views/tour.dart @@ -9,6 +9,16 @@ class ShowTour extends StatelessWidget { @override Widget build(BuildContext context) { + String title; + double fontSize; + if (tour.name.split(' ').length > 1) { + title = + tour.name.split(' ')[0] + '\n' + tour.name.split(' ')[1] + ' матч'; + fontSize = MediaQuery.of(context).size.width / 20; + } else { + title = tour.name; + fontSize = MediaQuery.of(context).size.width / 15; + } return Container( padding: const EdgeInsets.all(3.0), child: InkWell( @@ -20,10 +30,10 @@ class ShowTour extends StatelessWidget { child: CircleAvatar( radius: MediaQuery.of(context).size.width / 10, child: Text( - tour.name, - maxLines: 3, - style: - TextStyle(fontSize: MediaQuery.of(context).size.width / 15), + title, + textAlign: TextAlign.center, + maxLines: 2, + style: TextStyle(fontSize: fontSize), )), ), ); From 1c859f50e7c558973283f69aea1594e6db0e7cb6 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 13 May 2021 12:26:57 +0300 Subject: [PATCH 20/24] =?UTF-8?q?=D0=A0=D0=B0=D0=B7=D0=BD=D0=BE=D0=B5=20?= =?UTF-8?q?=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=82=D1=83=D1=80=D0=B0=20=D0=BD=D0=B0=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=BD=D1=8B=D1=85=20=D0=B2=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA?= =?UTF-8?q?=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/data/data.dart | 40 +++++++++++------- team_c_f/lib/pages/home.dart | 2 +- team_c_f/lib/pages/tour.dart | 46 ++++++++++++++------- team_c_f/lib/servises/schedule.dart | 12 ------ team_c_f/lib/servises/tour.dart | 30 ++++++++++++++ team_c_f/lib/storebloc/blocs/schedule.dart | 8 ++-- team_c_f/lib/storebloc/blocs/tour.dart | 4 +- team_c_f/lib/storebloc/models/tour.dart | 4 +- team_c_f/lib/storebloc/states/schedule.dart | 26 ++++++++---- team_c_f/lib/storebloc/states/tour.dart | 45 ++++++++++++++++---- team_c_f/lib/views/tour.dart | 7 +++- 11 files changed, 151 insertions(+), 73 deletions(-) create mode 100644 team_c_f/lib/servises/tour.dart diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 3cbc7ef..99e03e3 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -6,24 +6,23 @@ import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/servises/data.dart'; import 'package:team_c_f/servises/schedule.dart'; +import 'package:team_c_f/servises/tour.dart'; class Data with ChangeNotifier { bool downloadSuccessful = false; Data() { - DataService().initData().then((result) { - sortTour(); - sortData(); - downloadSuccessful = result; - notifyListeners(); - }); + initData(); } void clearData() { downloadSuccessful = false; notifyListeners(); + initData(); + } + + void initData(){ DataService().initData().then((result) { - sortTour(); sortData(); downloadSuccessful = result; notifyListeners(); @@ -41,8 +40,8 @@ class Data with ChangeNotifier { } static void sortData() { - players.sort((PlayerData a, b) => b.goals - .compareTo(a.goals)); // сортировка участников по количеству забитых + sortTour(); + sortPlayer(players: players); players.forEach( (PlayerData p) { p.prevPosition = players.indexOf(p) + 1; @@ -91,6 +90,19 @@ class Data with ChangeNotifier { ); }, ); // определение wdl для команд и количества пропущенных + sortTeam(teams: teams); + teams.forEach( + (TeamData t) { + t.prevPosition = teams.indexOf(t) + 1; + }, + ); // указание текущей позиции команды + } + + static Future getMeets(int stage) async { + return TourService().getMeets(stage: stage); + } + + static void sortTeam({required List teams}) { teams.sort((TeamData a, b) => (b.goals - b.missed) .compareTo(a.goals - a.missed)); // сортировка команд по разнице забитых teams.sort((TeamData a, b) => @@ -99,14 +111,10 @@ class Data with ChangeNotifier { b.goals.compareTo(a.goals)); // сортировка команд по количеству забитых teams.sort((TeamData a, b) => b.points.compareTo(a.points)); // сортировка команд по количеству очков - teams.forEach( - (TeamData t) { - t.prevPosition = teams.indexOf(t) + 1; - }, - ); // указание текущей позиции команды } - static Future getMeets(String stage) async { - return ScheduleService().getMeets(stage: stage); + static void sortPlayer({required List players}) { + players.sort((PlayerData a, b) => b.goals + .compareTo(a.goals)); // сортировка участников по количеству забитых } } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index 71a3123..0f94221 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -36,7 +36,7 @@ class HomePage extends StatelessWidget { ), BlocProvider( create: (BuildContext context) => TourBloc( - TourState(name: Data.currentTour.round), + TourState(round: Data.currentTour.round), ), ), ], diff --git a/team_c_f/lib/pages/tour.dart b/team_c_f/lib/pages/tour.dart index 58848cc..371a5d3 100644 --- a/team_c_f/lib/pages/tour.dart +++ b/team_c_f/lib/pages/tour.dart @@ -1,28 +1,42 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; -import 'package:team_c_f/storebloc/blocs/schedule.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart' as schedule; +import 'package:team_c_f/storebloc/blocs/tour.dart'; +import 'package:team_c_f/storebloc/states/tour.dart'; class TourPage extends StatelessWidget { final bool back; const TourPage({Key? key, required this.back}) : super(key: key); - @override Widget build(BuildContext context) { - return Column( - children: [ - if (back) - TextButton( - onPressed: () { - context.read().add( - ScheduleEvent(event: Event.unselectTour), - ); - }, - child: Text('Назад'), - ), - Container( - child: Text('Show tour'), + TourBloc bloc = back + ? context.watch().state.tourBloc! + : context.watch(); + return BlocBuilder( + bloc: bloc, + builder: (context, state) => Center( + child: Column( + children: [ + if (back) + TextButton( + onPressed: () { + context.read().add( + schedule.ScheduleEvent( + event: schedule.Event.unselectTour), + ); + }, + child: Text('Назад'), + ), + state.meets != null + ? Text('Show meets') + : TextButton( + onPressed: (){}, + child: Text('Выбрать матчи'), + ), + ], ), - ], + ), ); } } diff --git a/team_c_f/lib/servises/schedule.dart b/team_c_f/lib/servises/schedule.dart index 9963e9d..782ce4a 100644 --- a/team_c_f/lib/servises/schedule.dart +++ b/team_c_f/lib/servises/schedule.dart @@ -1,17 +1,5 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/meet.dart'; -import 'package:team_c_f/models/tour.dart'; class ScheduleService { - final CollectionReference _meetsCollection = - FirebaseFirestore.instance.collection('meets'); - - Future getMeets({required String stage}) { - return _meetsCollection.where('Round', isEqualTo: stage).get().then( - (QuerySnapshot response) => MeetData.fromMap( - data: response.docs.single.data(), - ), - ); - } } diff --git a/team_c_f/lib/servises/tour.dart b/team_c_f/lib/servises/tour.dart new file mode 100644 index 0000000..3da2213 --- /dev/null +++ b/team_c_f/lib/servises/tour.dart @@ -0,0 +1,30 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/models/meet.dart'; + +class TourService { + final CollectionReference _meetsCollection = + FirebaseFirestore.instance.collection('meets'); + + Future existsMeets({required int stage}) async { + DocumentReference doc = await _meetsCollection.add({'Test': 'test'}); + QuerySnapshot snapshot = await _meetsCollection.get(); + if (snapshot.docs.length != 1) { + _meetsCollection.doc(doc.id).delete(); + return _meetsCollection + .where('Round', isEqualTo: stage) + .get() + .then((QuerySnapshot response) => response.docs.length == 1); + } else { + _meetsCollection.doc(doc.id).delete(); + return false; + } + } + + Future getMeets({required int stage}) { + return _meetsCollection.where('Round', isEqualTo: stage).get().then( + (QuerySnapshot response) => MeetData.fromMap( + data: response.docs.single.data(), + ), + ); + } +} diff --git a/team_c_f/lib/storebloc/blocs/schedule.dart b/team_c_f/lib/storebloc/blocs/schedule.dart index 6e0846d..52ef918 100644 --- a/team_c_f/lib/storebloc/blocs/schedule.dart +++ b/team_c_f/lib/storebloc/blocs/schedule.dart @@ -5,10 +5,10 @@ import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; class ScheduleEvent { - final String? stage; + int? round; final Event event; - ScheduleEvent({this.stage, required this.event}); + ScheduleEvent({required this.event, this.round}); } enum Event { @@ -33,9 +33,7 @@ class ScheduleBloc extends Bloc { ); break; case Event.selectTour: - if (event.stage != null) { - yield state.copyWith(nameTour: event.stage, tourSelected: true); - } + yield state.copyWith(tourSelected: true, round: event.round); break; case Event.unselectTour: yield state.copyWith(tourSelected: false); diff --git a/team_c_f/lib/storebloc/blocs/tour.dart b/team_c_f/lib/storebloc/blocs/tour.dart index 0dbd2bc..9d3d0b3 100644 --- a/team_c_f/lib/storebloc/blocs/tour.dart +++ b/team_c_f/lib/storebloc/blocs/tour.dart @@ -6,7 +6,7 @@ import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:team_c_f/storebloc/states/tour.dart'; class TourEvent { - String? stage; + int? stage; final Event event; TourEvent({this.stage, required this.event}); @@ -32,7 +32,7 @@ class TourBloc extends Bloc { break; case Event.selectTour: if (event.stage != null) { - yield state; + yield await state.copyWith(round: event.stage); } break; } diff --git a/team_c_f/lib/storebloc/models/tour.dart b/team_c_f/lib/storebloc/models/tour.dart index 3e1614f..45c8d51 100644 --- a/team_c_f/lib/storebloc/models/tour.dart +++ b/team_c_f/lib/storebloc/models/tour.dart @@ -3,13 +3,13 @@ import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; class TourModel { + late int stage; late String name; late List>> result; - late List> matches; - late List> goals; TourModel({required TourData tour}) { name = tour.name ?? tour.round.toString(); + stage = tour.round; int round = tour.round - 1; result = tour.team.map( (List pair) { diff --git a/team_c_f/lib/storebloc/states/schedule.dart b/team_c_f/lib/storebloc/states/schedule.dart index ad181b7..3cc77c2 100644 --- a/team_c_f/lib/storebloc/states/schedule.dart +++ b/team_c_f/lib/storebloc/states/schedule.dart @@ -1,13 +1,16 @@ import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/storebloc/blocs/tour.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:team_c_f/storebloc/models/meet.dart'; +import 'package:team_c_f/storebloc/states/tour.dart'; class ScheduleState { bool get enableSchedule => Data.tours.isNotEmpty; late bool tourSelected = false; - late String nameTour; late List tours = []; + late int? round; + late TourBloc? tourBloc; ScheduleState() { tours = [...Data.tours.map((TourData tour) => TourModel(tour: tour))]; @@ -16,18 +19,23 @@ class ScheduleState { ScheduleState copyWith({ List? tours, MeetModel? meets, - String? nameTour, + int? nameTour, bool? tourSelected, - }) => - ScheduleState.all( - tours: tours ?? this.tours, - nameTour: nameTour ?? this.nameTour, - tourSelected: tourSelected ?? this.tourSelected, - ); + int? round, + }) { + if (round != null) tourBloc = TourBloc(TourState(round: round)); + return ScheduleState.all( + tours: tours ?? this.tours, + tourSelected: tourSelected ?? this.tourSelected, + round: round ?? this.round, + tourBloc: tourBloc ?? tourBloc, + ); + } ScheduleState.all({ required this.tours, - required this.nameTour, required this.tourSelected, + required this.round, + required this.tourBloc, }); } diff --git a/team_c_f/lib/storebloc/states/tour.dart b/team_c_f/lib/storebloc/states/tour.dart index dab1872..fef4806 100644 --- a/team_c_f/lib/storebloc/states/tour.dart +++ b/team_c_f/lib/storebloc/states/tour.dart @@ -1,18 +1,45 @@ import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/servises/tour.dart'; +import 'package:team_c_f/storebloc/models/meet.dart'; +import 'package:team_c_f/storebloc/models/tour.dart'; class TourState { - final int name; // цифровой + final int round; + MeetModel? meets; + late TourModel tour; - TourState({required this.name}); + TourState({required this.round}) { + tour = TourModel( + tour: Data.tours.where((TourData t) => t.round == round).single); + TourService() + .getMeets(stage: round) + .then((MeetData value) => meets = MeetModel(meet: value)); + } - TourState copyWith({ - int? name, - }) => - TourState.all( - name: name ?? this.name, - ); + Future copyWith({ + int? round, + MeetModel? meets, + TourModel? tour, + }) async { + if (round != null) { + if (await TourService().existsMeets(stage: round)) { + meets = MeetModel( + meet: await TourService().getMeets(stage: round), + ); + } + } + return TourState.all( + round: round ?? this.round, + meets: meets ?? this.meets, + tour: tour ?? this.tour, + ); + } TourState.all({ - required this.name + required this.round, + required this.meets, + required this.tour, }); } diff --git a/team_c_f/lib/views/tour.dart b/team_c_f/lib/views/tour.dart index 3d2522a..993304e 100644 --- a/team_c_f/lib/views/tour.dart +++ b/team_c_f/lib/views/tour.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:team_c_f/storebloc/blocs/schedule.dart'; +import 'package:team_c_f/storebloc/blocs/tour.dart' as tourBloc; import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:provider/provider.dart'; @@ -23,8 +24,12 @@ class ShowTour extends StatelessWidget { padding: const EdgeInsets.all(3.0), child: InkWell( onTap: () { + // context.read().add( + // tourBloc.TourEvent( + // event: tourBloc.Event.selectTour, stage: tour.stage), + // ); context.read().add( - ScheduleEvent(event: Event.selectTour, stage: tour.name), + ScheduleEvent(event: Event.selectTour, round: tour.stage), ); }, child: CircleAvatar( From 547b41f79997cc9fd50250ce3bf319132918bfc0 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Thu, 13 May 2021 18:48:14 +0300 Subject: [PATCH 21/24] =?UTF-8?q?=D0=9E=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B0=D1=82=D1=87=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=B0=D0=B6=D0=B4=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D1=82=D1=83=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/pages/team.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/team_c_f/lib/pages/team.dart b/team_c_f/lib/pages/team.dart index bc55987..1f2725b 100644 --- a/team_c_f/lib/pages/team.dart +++ b/team_c_f/lib/pages/team.dart @@ -24,6 +24,10 @@ class TeamPage extends StatelessWidget { child: Column( children: [ Card( + color: Colors.cyan[300], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), child: ListTile( leading: CircleAvatar( // Показывает место в таблице бомбардиров From 577c8c43532af129f6c8d8f640c964aaf05043a7 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Mon, 17 May 2021 21:30:40 +0300 Subject: [PATCH 22/24] =?UTF-8?q?=D0=9E=D1=82=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B0=D1=82=D1=87=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BD?= =?UTF-8?q?=D0=BE=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/meet.dart | 59 +++++ team_c_f/lib/components/selectteam.dart | 4 +- team_c_f/lib/data/data.dart | 8 +- team_c_f/lib/models/choicemeet.dart | 47 ++++ team_c_f/lib/models/meet.dart | 31 ++- team_c_f/lib/models/meets.dart | 48 ++++ team_c_f/lib/old/page/selectmatch.dart | 61 +++-- team_c_f/lib/pages/schedule.dart | 5 +- team_c_f/lib/pages/selectmeets.dart | 217 ++++++++++++++++++ team_c_f/lib/pages/tour.dart | 72 ++++-- team_c_f/lib/servises/createschedule.dart | 11 +- team_c_f/lib/servises/data.dart | 17 +- team_c_f/lib/servises/schedule.dart | 3 - team_c_f/lib/servises/selectmeets.dart | 16 ++ team_c_f/lib/servises/servises.dart | 14 +- team_c_f/lib/servises/tour.dart | 23 +- team_c_f/lib/store/selectteam/selectteam.dart | 2 +- .../lib/storebloc/blocs/createschedule.dart | 12 + team_c_f/lib/storebloc/blocs/schedule.dart | 8 +- team_c_f/lib/storebloc/blocs/selectmeets.dart | 132 +++++++++++ team_c_f/lib/storebloc/blocs/tour.dart | 12 +- team_c_f/lib/storebloc/models/meet.dart | 17 +- team_c_f/lib/storebloc/states/schedule.dart | 6 +- .../lib/storebloc/states/selectmeets.dart | 34 +++ team_c_f/lib/storebloc/states/tour.dart | 28 +-- team_c_f/lib/views/meets.dart | 63 +++++ team_c_f/lib/views/player.dart | 4 + team_c_f/lib/views/team.dart | 12 +- team_c_f/lib/views/tour.dart | 107 ++++++--- team_c_f/lib/views/touravatar.dart | 48 ++++ team_c_f/pubspec.lock | 19 +- team_c_f/pubspec.yaml | 2 +- 32 files changed, 980 insertions(+), 162 deletions(-) create mode 100644 team_c_f/lib/components/meet.dart create mode 100644 team_c_f/lib/models/choicemeet.dart create mode 100644 team_c_f/lib/models/meets.dart create mode 100644 team_c_f/lib/pages/selectmeets.dart create mode 100644 team_c_f/lib/servises/selectmeets.dart create mode 100644 team_c_f/lib/storebloc/blocs/selectmeets.dart create mode 100644 team_c_f/lib/storebloc/states/selectmeets.dart create mode 100644 team_c_f/lib/views/meets.dart create mode 100644 team_c_f/lib/views/touravatar.dart diff --git a/team_c_f/lib/components/meet.dart b/team_c_f/lib/components/meet.dart new file mode 100644 index 0000000..fc440bd --- /dev/null +++ b/team_c_f/lib/components/meet.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:intl/intl.dart'; + +class MeetView extends StatelessWidget { + final MeetData meetData; + const MeetView({Key? key, required this.meetData}) : super(key: key); + + @override + Widget build(BuildContext context) { + DateTime date = DateFormat('yyyy-MM-dd HH:mm').parse(meetData.date); + String status = meetData == 'Не начат' + ? date.day == DateTime.now().day + ? DateFormat('HH:mm').format(date) + : DateFormat('dd.MM').format(date) + : meetData.status; + return Padding( + padding: const EdgeInsets.all(2.0), + child: Container( + padding: const EdgeInsets.all(8.0), + color: meetData.started ? Colors.green[100] : Colors.yellow[200], + width: MediaQuery.of(context).size.width / 2 - 15, + child: Column( + children: [ + Text(status), + Table( + columnWidths: { + 0: IntrinsicColumnWidth(flex: 0.9), + 1: IntrinsicColumnWidth(flex: 0.1) + }, + children: [ + TableRow( + children: [ + Text(meetData.team.first), + if (!meetData.started) + Text( + meetData.score.first.toString(), + textAlign: TextAlign.right, + ), + ], + ), + TableRow( + children: [ + Text(meetData.team.last), + if (!meetData.started) + Text( + meetData.score.last.toString(), + textAlign: TextAlign.right, + ), + ], + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/team_c_f/lib/components/selectteam.dart b/team_c_f/lib/components/selectteam.dart index b8673c6..3a2a447 100644 --- a/team_c_f/lib/components/selectteam.dart +++ b/team_c_f/lib/components/selectteam.dart @@ -139,7 +139,7 @@ class SelectTeamView extends StatelessWidget { selectTeam.registrateTeam().then( (_) { context.read().validateInApp(); - context.read().clearData(); + context.read().refreshData(); if (updateMyTeam) context .read() @@ -154,7 +154,7 @@ class SelectTeamView extends StatelessWidget { selectTeam.assertTeam().then( (_) { context.read().validateInApp(); - context.read().clearData(); + context.read().refreshData(); if (updateMyTeam) context .read() diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 99e03e3..70c1352 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -1,11 +1,10 @@ import 'package:flutter/material.dart'; import 'package:team_c_f/models/currenttour.dart'; -import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/servises/data.dart'; -import 'package:team_c_f/servises/schedule.dart'; import 'package:team_c_f/servises/tour.dart'; class Data with ChangeNotifier { @@ -15,7 +14,7 @@ class Data with ChangeNotifier { initData(); } - void clearData() { + void refreshData() { downloadSuccessful = false; notifyListeners(); initData(); @@ -33,6 +32,7 @@ class Data with ChangeNotifier { static late List players; static late List teams; static late List tours; + static late List meets; static void sortTour() { tours.sort((TourData a, b) => @@ -98,7 +98,7 @@ class Data with ChangeNotifier { ); // указание текущей позиции команды } - static Future getMeets(int stage) async { + static Future getMeets(int stage) async { return TourService().getMeets(stage: stage); } diff --git a/team_c_f/lib/models/choicemeet.dart b/team_c_f/lib/models/choicemeet.dart new file mode 100644 index 0000000..62544a0 --- /dev/null +++ b/team_c_f/lib/models/choicemeet.dart @@ -0,0 +1,47 @@ +import 'package:html/dom.dart'; +import 'package:intl/intl.dart'; + +class ChoiceMeetData { + final List team; + final DateTime date; + late bool selected; + + ChoiceMeetData({ + required this.team, + required this.date, + required this.selected, + }); + + factory ChoiceMeetData.fromHtml({ + required String date, + required Element html, + }) { + List team = [ + html.getElementsByClassName('owner-td').single.text.replaceAll( + '\n', + '', + ), + html.getElementsByClassName('guests-td').single.text.replaceAll( + '\n', + '', + ), + ]; + String time = html.getElementsByClassName('alLeft gray-text').first.text; + time = date + ' ' + (time != '—' ? time : '00:00'); + DateTime dateTime = DateFormat('yyyy-MM-dd HH:mm').parse(time); + bool selected = false; + return ChoiceMeetData( + team: team, + date: dateTime, + selected: selected, + ); + } + + ChoiceMeetData copyWith({required bool selected}) { + return ChoiceMeetData( + team: this.team, + date: this.date, + selected: selected, + ); + } +} diff --git a/team_c_f/lib/models/meet.dart b/team_c_f/lib/models/meet.dart index 5ebcfa7..17add45 100644 --- a/team_c_f/lib/models/meet.dart +++ b/team_c_f/lib/models/meet.dart @@ -1,35 +1,50 @@ class MeetData { - final String round; final List team; - final DateTime date; - final List score; + final String date; + late List score; final bool started; + late String status; MeetData({ - required this.round, required this.team, required this.date, required this.score, required this.started, + required this.status, }); factory MeetData.fromMap({required Map data}) { return MeetData( - round: data['Round'], - team: data['Team'], + team: data['Team'].cast(), date: data['Date'], - score: data['Score'], + score: data['Score'].cast(), started: data['Started'], + status: data['Status'], ); } Map toMap() { return { - 'Round': round, 'Team': team, 'Date': date, 'Score': score, 'Started': started, + 'Status': status, }; } + + String toString() { + return '${team.first} - ${team.last}|$date|${score.first}:${score.last}|$started|$status'; + } + + factory MeetData.fromString({required String data}) { + List split = data.split('|'); + return MeetData( + team: split[0].split(' - '), + date: split[1], + score: split[2].split(':').map((String goal) => int.parse(goal)).toList(), + started: bool.fromEnvironment(split[3]), + status: split[4], + ); + } } diff --git a/team_c_f/lib/models/meets.dart b/team_c_f/lib/models/meets.dart new file mode 100644 index 0000000..8397b33 --- /dev/null +++ b/team_c_f/lib/models/meets.dart @@ -0,0 +1,48 @@ +import 'meet.dart'; + +class MeetsData { + late String uid; + final int round; + final List meets; + final String deadline; + final bool started; + + MeetsData({ + required this.round, + required this.meets, + required this.deadline, + required this.started, + }); + + factory MeetsData.fromMap( + {required Map data, required String uid}) { + List a = []; + if (data['Meets'].isNotEmpty) + a.addAll( + [ + ...data['Meets'] + .map( + (meet) => MeetData.fromString(data: meet), + ) + .toList(), + ], + ); + MeetsData meets = MeetsData( + round: data['Round'], + meets: a, + deadline: data['Deadline'], + started: data['Started'], + ); + meets.uid = uid; + return meets; + } + + Map toMap() { + return { + 'Round': round, + 'Meets': meets.map((e) => e.toString()).toList(), + 'Deadline': deadline, + 'Started': started, + }; + } +} diff --git a/team_c_f/lib/old/page/selectmatch.dart b/team_c_f/lib/old/page/selectmatch.dart index c2548dd..d51e1ef 100644 --- a/team_c_f/lib/old/page/selectmatch.dart +++ b/team_c_f/lib/old/page/selectmatch.dart @@ -3,9 +3,6 @@ import 'package:provider/provider.dart'; import 'package:team_c_f/old/data/shortmatch.dart'; import 'package:team_c_f/old/servise/htmlparse.dart'; import 'package:team_c_f/old/servise/make.dart'; -import 'package:intl/intl.dart'; -// ignore: import_of_legacy_library_into_null_safe -import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker; import 'package:http/http.dart' as http; class SelectMatch extends StatefulWidget { @@ -28,16 +25,18 @@ class _SelectMatchState extends State { (date) { http.Client() .get(Uri.parse('https://www.sports.ru/football/match/$date/')) - .then((value) { - context.read().add( - [ - ...getMatchs( - body: value.body, - date: '$date', - ) - ], - ); - }); + .then( + (value) { + context.read().add( + [ + ...getMatchs( + body: value.body, + date: '$date', + ) + ], + ); + }, + ); }, ); } @@ -59,24 +58,24 @@ class _SelectMatchState extends State { ElevatedButton( onPressed: () { range.clear(); - DateRangePicker.showDatePicker( - context: context, - initialFirstDate: DateTime.now(), - initialLastDate: DateTime.now(), - firstDate: DateTime(2021), - lastDate: DateTime(2040), - ).then((value) { - setState(() { - period = value; - for (DateTime i = value.first; - i.isBefore(value.last.add(Duration(minutes: 1))); - i = i.add(Duration(days: 1))) { - range.add(DateFormat('yyyy-MM-dd').format(i)); - } - }); - context.read().data.clear(); - download(); - }); + // DateRangePicker.showDatePicker( + // context: context, + // initialFirstDate: DateTime.now(), + // initialLastDate: DateTime.now(), + // firstDate: DateTime(2021), + // lastDate: DateTime(2040), + // ).then((value) { + // setState(() { + // period = value; + // for (DateTime i = value.first; + // i.isBefore(value.last.add(Duration(minutes: 1))); + // i = i.add(Duration(days: 1))) { + // range.add(DateFormat('yyyy-MM-dd').format(i)); + // } + // }); + // context.read().data.clear(); + // download(); + // }); }, child: Text('Выбрать даты'), ), diff --git a/team_c_f/lib/pages/schedule.dart b/team_c_f/lib/pages/schedule.dart index b5e6830..8c17be5 100644 --- a/team_c_f/lib/pages/schedule.dart +++ b/team_c_f/lib/pages/schedule.dart @@ -8,7 +8,7 @@ import 'package:team_c_f/storebloc/states/createschedule.dart'; import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; -import 'package:team_c_f/views/tour.dart'; +import 'package:team_c_f/views/touravatar.dart'; class SchedulePage extends StatelessWidget { @override @@ -22,7 +22,6 @@ class SchedulePage extends StatelessWidget { : Container( height: MediaQuery.of(context).size.height, width: double.infinity, - color: Colors.amber, child: Wrap( alignment: WrapAlignment.spaceAround, runAlignment: WrapAlignment.center, @@ -30,7 +29,7 @@ class SchedulePage extends StatelessWidget { runSpacing: 20, children: [ ...bloc.state.tours.map( - (TourModel tour) => ShowTour(tour: tour), + (TourModel tour) => ShowTourAvatar(tour: tour), ), ], ), diff --git a/team_c_f/lib/pages/selectmeets.dart b/team_c_f/lib/pages/selectmeets.dart new file mode 100644 index 0000000..7afeba5 --- /dev/null +++ b/team_c_f/lib/pages/selectmeets.dart @@ -0,0 +1,217 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/models/choicemeet.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/meets.dart'; +import 'package:team_c_f/servises/selectmeets.dart'; +import 'package:team_c_f/servises/servises.dart'; +import 'package:team_c_f/storebloc/blocs/selectmeets.dart'; +import 'package:team_c_f/storebloc/blocs/tour.dart' as tourBloc; +import 'package:team_c_f/storebloc/states/selectmeets.dart'; +import 'package:flutter_date_pickers/flutter_date_pickers.dart'; +import 'package:intl/intl.dart'; + +class SelectMeetsPage extends StatelessWidget { + final int round; + const SelectMeetsPage({Key? key, required this.round}) : super(key: key); + + @override + Widget build(BuildContext context) { + SelectMeetsBloc bloc = SelectMeetsBloc(SelectMeetsState()); + return BlocBuilder( + bloc: bloc, + builder: (context, state) => Container( + child: SafeArea( + child: Scaffold( + body: Center( + child: Column( + children: [ + Expanded( + child: ListView( + children: [ + RangePicker( + selectedPeriod: DatePeriod( + bloc.state.dateRange.isNotEmpty + ? bloc.state.dateRange.first + : DateTime.now().add( + Duration(days: 3), + ), + bloc.state.dateRange.isNotEmpty + ? bloc.state.dateRange.last + : DateTime.now().add( + Duration(days: 4), + ), + ), + firstDate: DateTime.now().add( + Duration(days: 2), + ), + lastDate: DateTime(2099), + onChanged: (DatePeriod period) { + bloc.add( + SelectMeetsEvent( + event: Event.changeRange, + range: [period.start, period.end], + ), + ); + }, + ), + ...bloc.state.allMeets.keys.map((String date) { + int countDate = bloc.state.allMeets[date]!.values + .map( + (list) => list + .where((element) => element.selected) + .length, + ) + .reduce((value, element) => value + element); + return Column( + children: [ + TextButton( + onPressed: () { + bloc.add( + SelectMeetsEvent( + event: Event.changeDateState, + key: date, + ), + ); + }, + child: Text( + date + showSelectIn(countDate), + ), + ), + if (bloc.state.openDate[date]!) + ...bloc.state.allMeets[date]!.keys.map( + (String tournament) { + int countTournament = bloc + .state.allMeets[date]![tournament]! + .where((element) => element.selected) + .length; + return Column( + children: [ + TextButton( + onPressed: () { + bloc.add( + SelectMeetsEvent( + event: + Event.changeTournamentState, + key: date + tournament, + ), + ); + }, + child: Text( + tournament + + showSelectIn( + countTournament, + ), + ), + ), + if (bloc.state + .openTornament[date + tournament]!) + ...bloc.state + .allMeets[date]![tournament]! + .map( + (ChoiceMeetData meetData) { + return Card( + child: CheckboxListTile( + value: meetData.selected, + onChanged: (bool? a) { + bloc.add( + SelectMeetsEvent( + event: Event.selectMeet, + meet: meetData, + choice: a, + ), + ); + }, + title: Text(DateFormat( + 'HH:mm ') + .format( + meetData.date) + + meetData.team.first + + ' - ' + + meetData.team.last), + ), + ); + }, + ), + ], + ); + }, + ).toList(), + ], + ); + }).toList(), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: TextButton( + onPressed: bloc.state.selectedMeets.length == 10 + ? () { + bloc.state.selectedMeets + .sort((a, b) => a.date.compareTo(b.date)); + List team = []; + bloc.state.selectedMeets.forEach( + (ChoiceMeetData meet) { + team.addAll(meet.team); + }, + ); + SelectMeetsService().cteateMeet( + meet: MeetsData( + round: round, + meets: bloc.state.selectedMeets + .map( + (ChoiceMeetData choiceMeetData) => + MeetData( + date: DateFormat('yyyy-MM-dd HH:mm') + .format(choiceMeetData.date), + score: [0, 0], + started: false, + team: [ + choiceMeetData.team.first, + choiceMeetData.team.last + ], + status: 'Не начат', + ), + ) + .toList(), + deadline: + DateFormat('yyyy-MM-dd HH:mm').format( + bloc.state.selectedMeets[0].date.add( + Duration(hours: -1), + ), + ), + started: false, + ), + // MeetsData( + // round: round, + // team: team, + // date: DateFormat('yyyy-MM-dd HH:mm').format( + // bloc.state.selectedMeets[0].date.add( + // Duration(hours: -1), + // ), + // ), + // score: [], + // started: false, + // ), + ); + Navigator.pop( + context, + tourBloc.TourEvent( + event: tourBloc.Event.selectMeets, + ), + ); + } + : null, + child: Text('Выбрано ${bloc.state.selectedMeets.length}'), + ), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/team_c_f/lib/pages/tour.dart b/team_c_f/lib/pages/tour.dart index 371a5d3..f7b97ba 100644 --- a/team_c_f/lib/pages/tour.dart +++ b/team_c_f/lib/pages/tour.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/pages/selectmeets.dart'; import 'package:team_c_f/storebloc/blocs/schedule.dart' as schedule; import 'package:team_c_f/storebloc/blocs/tour.dart'; import 'package:team_c_f/storebloc/states/tour.dart'; +import 'package:team_c_f/views/meets.dart'; +import 'package:team_c_f/views/tour.dart'; class TourPage extends StatelessWidget { final bool back; @@ -15,26 +18,55 @@ class TourPage extends StatelessWidget { : context.watch(); return BlocBuilder( bloc: bloc, - builder: (context, state) => Center( - child: Column( - children: [ - if (back) - TextButton( - onPressed: () { - context.read().add( - schedule.ScheduleEvent( - event: schedule.Event.unselectTour), - ); - }, - child: Text('Назад'), - ), - state.meets != null - ? Text('Show meets') - : TextButton( - onPressed: (){}, - child: Text('Выбрать матчи'), - ), - ], + builder: (context, state) => SingleChildScrollView( + child: Center( + child: Column( + children: [ + if (back) + TextButton( + onPressed: () { + context.read().add( + schedule.ScheduleEvent( + event: schedule.Event.unselectTour), + ); + }, + child: Text('Назад'), + ), + state.meets.meets.isNotEmpty + ? Column( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: ShowMeets( + meetsModel: state.meets, + ), + ), + TextButton( + onPressed: null, + child: Text('Оставить прогноз'), + ), + ], + ) + : TextButton( + onPressed: () { + Navigator.of(context) + .push( + MaterialPageRoute( + builder: (context) => + SelectMeetsPage(round: bloc.state.round), + ), + ) + .then( + (TourEvent? event) { + if (event != null) bloc.add(event); + }, + ); + }, + child: Text('Выбрать матчи'), + ), + ShowTour(tour: state.tour), + ], + ), ), ), ); diff --git a/team_c_f/lib/servises/createschedule.dart b/team_c_f/lib/servises/createschedule.dart index 6c7699e..582e90b 100644 --- a/team_c_f/lib/servises/createschedule.dart +++ b/team_c_f/lib/servises/createschedule.dart @@ -1,13 +1,15 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/tour.dart'; class CreateScheduleService { final CollectionReference _scheduleCollection = FirebaseFirestore.instance.collection('schedule'); + final CollectionReference _meetsCollection = + FirebaseFirestore.instance.collection('meets'); void create() { - Map a = Data.tours.first.toMap(); Data.tours.forEach( (TourData tour) { _scheduleCollection.add( @@ -15,5 +17,12 @@ class CreateScheduleService { ); }, ); + Data.meets.forEach( + (MeetsData meets) { + _meetsCollection.add( + meets.toMap(), + ); + }, + ); } } diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index f790ed5..6c72d9d 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -1,6 +1,7 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:team_c_f/models/currenttour.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; @@ -14,14 +15,15 @@ class DataService { FirebaseFirestore.instance.collection('currentTour'); final CollectionReference _toursCollection = FirebaseFirestore.instance.collection('schedule'); - // final CollectionReference _forecastsCollection = - // FirebaseFirestore.instance.collection('forecasts'); + final CollectionReference _meetsCollection = + FirebaseFirestore.instance.collection('meets'); Future initData() async { Data.currentTour = await getCurrentTour(); Data.players = await getPlayers(); Data.teams = await getTeams(); Data.tours = await getTours(); + Data.meets = await getMeets(); return true; } @@ -71,4 +73,15 @@ class DataService { .toList(), ); } + + Future> getMeets() { + return _meetsCollection.get().then( + (QuerySnapshot response) => response.docs + .map( + (QueryDocumentSnapshot doc) => + MeetsData.fromMap(data: doc.data(), uid: doc.id), + ) + .toList(), + ); + } } diff --git a/team_c_f/lib/servises/schedule.dart b/team_c_f/lib/servises/schedule.dart index 782ce4a..1c08f76 100644 --- a/team_c_f/lib/servises/schedule.dart +++ b/team_c_f/lib/servises/schedule.dart @@ -1,5 +1,2 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/models/meet.dart'; - class ScheduleService { } diff --git a/team_c_f/lib/servises/selectmeets.dart b/team_c_f/lib/servises/selectmeets.dart new file mode 100644 index 0000000..90c1fbf --- /dev/null +++ b/team_c_f/lib/servises/selectmeets.dart @@ -0,0 +1,16 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meets.dart'; + +class SelectMeetsService { + final CollectionReference _meetsCollection = + FirebaseFirestore.instance.collection('meets'); + + void cteateMeet({required MeetsData meet}) { + MeetsData current = Data.meets.where((element) => element.round == meet.round).single; + meet.uid = current.uid; + Data.meets.remove(current); + Data.meets.add(meet); + _meetsCollection.doc(meet.uid).update(meet.toMap()); + } +} diff --git a/team_c_f/lib/servises/servises.dart b/team_c_f/lib/servises/servises.dart index da3e03c..63ef156 100644 --- a/team_c_f/lib/servises/servises.dart +++ b/team_c_f/lib/servises/servises.dart @@ -2,6 +2,16 @@ import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/team.dart'; import 'package:team_c_f/models/tour.dart'; +String showSelectIn(int count) { + return count > 0 + ? count == 1 + ? ' (Выбран 1 матч)' + : count < 5 + ? ' (Выбрано $count матча)' + : ' (Выбрано $count матчей)' + : ''; +} + String showPoints(int points) { // Функция изменения склонения слова "N очков" return points.toString() + @@ -68,12 +78,12 @@ String showTours({required int tours}) { List createSchedule(int circles) { List registTeam = Data.teams.where((TeamData team) => team.players.length == 3).toList(); - List teams =['1', '2', '3', '4', '5']; + List teams = ['1', '2', '3', '4', '5']; // registTeam // .map((TeamData team) => team.name) // .toList(); //['1', '2', '3', '4', '5']; List curr = []; - int count = 5;//registTeam.length; + int count = 5; //registTeam.length; int tour = (count.isEven ? count - 1 : count); for (int q = 0; q < circles; q++) { for (int i = 0; i < tour; i++) { diff --git a/team_c_f/lib/servises/tour.dart b/team_c_f/lib/servises/tour.dart index 3da2213..5db6389 100644 --- a/team_c_f/lib/servises/tour.dart +++ b/team_c_f/lib/servises/tour.dart @@ -1,5 +1,5 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/meets.dart'; class TourService { final CollectionReference _meetsCollection = @@ -10,21 +10,24 @@ class TourService { QuerySnapshot snapshot = await _meetsCollection.get(); if (snapshot.docs.length != 1) { _meetsCollection.doc(doc.id).delete(); - return _meetsCollection - .where('Round', isEqualTo: stage) - .get() - .then((QuerySnapshot response) => response.docs.length == 1); + return (await _meetsCollection.where('Round', isEqualTo: stage).get()) + .docs + .length == + 1; } else { _meetsCollection.doc(doc.id).delete(); return false; } } - Future getMeets({required int stage}) { - return _meetsCollection.where('Round', isEqualTo: stage).get().then( - (QuerySnapshot response) => MeetData.fromMap( + Future getMeets({required int stage}) async { + QuerySnapshot response = + await _meetsCollection.where('Round', isEqualTo: stage).get(); + return response.docs.length != 0 + ? MeetsData.fromMap( data: response.docs.single.data(), - ), - ); + uid: response.docs.single.id, + ) + : null; } } diff --git a/team_c_f/lib/store/selectteam/selectteam.dart b/team_c_f/lib/store/selectteam/selectteam.dart index 64a8d64..d9df678 100644 --- a/team_c_f/lib/store/selectteam/selectteam.dart +++ b/team_c_f/lib/store/selectteam/selectteam.dart @@ -71,7 +71,7 @@ abstract class _SelectTeamBase with Store { uid: uId, docId: docId, ); - Data().clearData(); + Data().refreshData(); return docId == null ? await SelectTeamService().registratePlayer( player: p, diff --git a/team_c_f/lib/storebloc/blocs/createschedule.dart b/team_c_f/lib/storebloc/blocs/createschedule.dart index 8d993af..5718504 100644 --- a/team_c_f/lib/storebloc/blocs/createschedule.dart +++ b/team_c_f/lib/storebloc/blocs/createschedule.dart @@ -1,5 +1,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meets.dart'; +import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/servises/createschedule.dart'; import 'package:team_c_f/servises/servises.dart'; import 'package:team_c_f/storebloc/states/createschedule.dart'; @@ -19,6 +21,16 @@ class CreateScheduleBloc break; case CreateScheduleEvent.createSchedule: Data.tours = createSchedule(state.circle); + Data.tours.forEach((TourData tour) { + Data.meets.add( + MeetsData( + deadline: '2099-01-01 00:00', + meets: [], + round: tour.round, + started: false, + ), + ); + }); CreateScheduleService().create(); yield state; break; diff --git a/team_c_f/lib/storebloc/blocs/schedule.dart b/team_c_f/lib/storebloc/blocs/schedule.dart index 52ef918..7f3b2f0 100644 --- a/team_c_f/lib/storebloc/blocs/schedule.dart +++ b/team_c_f/lib/storebloc/blocs/schedule.dart @@ -1,8 +1,10 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/storebloc/blocs/tour.dart'; import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; +import 'package:team_c_f/storebloc/states/tour.dart'; class ScheduleEvent { int? round; @@ -33,7 +35,11 @@ class ScheduleBloc extends Bloc { ); break; case Event.selectTour: - yield state.copyWith(tourSelected: true, round: event.round); + state.tourBloc = TourBloc( + TourState(round: event.round!), + ); + yield state.copyWith( + tourSelected: true, round: event.round!, tourBloc: state.tourBloc); break; case Event.unselectTour: yield state.copyWith(tourSelected: false); diff --git a/team_c_f/lib/storebloc/blocs/selectmeets.dart b/team_c_f/lib/storebloc/blocs/selectmeets.dart new file mode 100644 index 0000000..0578127 --- /dev/null +++ b/team_c_f/lib/storebloc/blocs/selectmeets.dart @@ -0,0 +1,132 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/models/choicemeet.dart'; +import 'package:team_c_f/storebloc/states/selectmeets.dart'; +import 'package:http/http.dart'; +import 'package:intl/intl.dart'; +import 'package:html/dom.dart'; +import 'package:html/parser.dart'; + +class SelectMeetsEvent { + final String? key; + final List? range; + final ChoiceMeetData? meet; + final bool? choice; + final Event event; + + SelectMeetsEvent({ + this.choice, + this.key, + this.range, + this.meet, + required this.event, + }); +} + +enum Event { + changeRange, + selectMeet, + changeDateState, + changeTournamentState, +} + +class SelectMeetsBloc extends Bloc { + SelectMeetsBloc(SelectMeetsState initialState) : super(initialState); + + @override + Stream mapEventToState(SelectMeetsEvent event) async* { + switch (event.event) { + case Event.changeRange: + if (event.range != null) { + List range = []; + Map>> allMeets = {}; + Map openDate = {}; + Map openTournament = {}; + for (DateTime i = event.range!.first; + i.isBefore(event.range!.last); + i = i.add( + Duration(days: 1), + ),) { + Map> map = {}; + range.add(i); + String date = DateFormat('yyyy-MM-dd').format(i); + openDate.addAll({date: false}); + Document doc = parse((await Client().get( + Uri.parse('https://www.sports.ru/football/match/$date/'))) + .body); + Element element = doc.getElementsByClassName('match-center').single; + element = element.getElementsByTagName('li').first; + List divs = [...element.children]; + divs.removeWhere((Element el) => + el.innerHtml.contains('Реклама') || + el.innerHtml.contains('Матч дня')); + String tournament = ''; + for (int index = 0; index < divs.length; index++) { + if (index.isEven) { + tournament = divs[index].text.replaceAll('\n', ''); + openTournament.addAll({date + tournament: false}); + } else { + map[tournament] = [ + ...divs[index].getElementsByTagName('tr').map( + (Element meet) => ChoiceMeetData.fromHtml( + html: meet, + date: date, + ), + ) + ]; + } + } + allMeets[date] = map; + } + yield state.copyWith( + dateRange: range, + allMeets: allMeets, + openDate: openDate, + openTornament: openTournament, + ); + } + break; + case Event.selectMeet: + if (event.meet != null) { + state.allMeets.forEach( + (date, value) { + value.forEach( + (tournament, list) { + list.where((element) => element == event.meet). + forEach( + (sel) { + sel.selected = event.choice!; + }, + ); + }, + ); + }, + ); + if (event.choice!) + state.selectedMeets.add( + event.meet!, + ); + else + state.selectedMeets.removeWhere( + (element) => element == event.meet!, + ); + yield state.copyWith( + allMeets: state.allMeets, + selectedMeets: state.selectedMeets, + ); + } + break; + case Event.changeDateState: + if (event.key != null) { + state.openDate[event.key!] = !state.openDate[event.key]!; + yield state.copyWith(openDate: state.openDate); + } + break; + case Event.changeTournamentState: + if (event.key != null) { + state.openTornament[event.key!] = !state.openTornament[event.key]!; + yield state.copyWith(openTornament: state.openTornament); + } + break; + } + } +} diff --git a/team_c_f/lib/storebloc/blocs/tour.dart b/team_c_f/lib/storebloc/blocs/tour.dart index 9d3d0b3..e79e51e 100644 --- a/team_c_f/lib/storebloc/blocs/tour.dart +++ b/team_c_f/lib/storebloc/blocs/tour.dart @@ -1,8 +1,5 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/tour.dart'; -import 'package:team_c_f/storebloc/states/schedule.dart'; -import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:team_c_f/storebloc/states/tour.dart'; class TourEvent { @@ -28,11 +25,16 @@ class TourBloc extends Bloc { yield state; break; case Event.selectMeets: - yield state; + Data().refreshData(); + yield state.copyWith(round: state.round); break; case Event.selectTour: if (event.stage != null) { - yield await state.copyWith(round: event.stage); + yield state.copyWith( + round: event.stage, + meetsData: Data.meets + .where((element) => element.round == event.stage) + .single); } break; } diff --git a/team_c_f/lib/storebloc/models/meet.dart b/team_c_f/lib/storebloc/models/meet.dart index f0c5188..5637e53 100644 --- a/team_c_f/lib/storebloc/models/meet.dart +++ b/team_c_f/lib/storebloc/models/meet.dart @@ -1,15 +1,16 @@ import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/meets.dart'; -class MeetModel { - late List team = []; - late List score = []; - late String info; +class MeetsModel { + late int round; + late String deadline; + late List meets; late bool started; - MeetModel({required MeetData meet}) { - team = meet.team; - score = meet.score; - info = meet.date.toString(); + MeetsModel({required MeetsData meet}) { started = meet.started; + deadline = meet.deadline; + meets = meet.meets; + round = meet.round; } } diff --git a/team_c_f/lib/storebloc/states/schedule.dart b/team_c_f/lib/storebloc/states/schedule.dart index 3cc77c2..a1f7dc4 100644 --- a/team_c_f/lib/storebloc/states/schedule.dart +++ b/team_c_f/lib/storebloc/states/schedule.dart @@ -2,8 +2,6 @@ import 'package:team_c_f/data/data.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/storebloc/blocs/tour.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; -import 'package:team_c_f/storebloc/models/meet.dart'; -import 'package:team_c_f/storebloc/states/tour.dart'; class ScheduleState { bool get enableSchedule => Data.tours.isNotEmpty; @@ -18,12 +16,12 @@ class ScheduleState { ScheduleState copyWith({ List? tours, - MeetModel? meets, + //MeetsModel? meets, int? nameTour, bool? tourSelected, int? round, + TourBloc? tourBloc, }) { - if (round != null) tourBloc = TourBloc(TourState(round: round)); return ScheduleState.all( tours: tours ?? this.tours, tourSelected: tourSelected ?? this.tourSelected, diff --git a/team_c_f/lib/storebloc/states/selectmeets.dart b/team_c_f/lib/storebloc/states/selectmeets.dart new file mode 100644 index 0000000..fc6060a --- /dev/null +++ b/team_c_f/lib/storebloc/states/selectmeets.dart @@ -0,0 +1,34 @@ +import 'package:team_c_f/models/choicemeet.dart'; + +class SelectMeetsState { + List dateRange = []; + Map>> allMeets = {}; + Map openDate = {}; + Map openTornament = {}; + List selectedMeets = []; + + SelectMeetsState(); + + SelectMeetsState copyWith({ + List? dateRange, + Map>>? allMeets, + Map? openDate, + Map? openTornament, + List? selectedMeets, + }) => + SelectMeetsState.all( + dateRange: dateRange ?? this.dateRange, + allMeets: allMeets ?? this.allMeets, + openDate: openDate ?? this.openDate, + openTornament: openTornament ?? this.openTornament, + selectedMeets: selectedMeets ?? this.selectedMeets, + ); + + SelectMeetsState.all({ + required this.dateRange, + required this.allMeets, + required this.openDate, + required this.openTornament, + required this.selectedMeets, + }); +} diff --git a/team_c_f/lib/storebloc/states/tour.dart b/team_c_f/lib/storebloc/states/tour.dart index fef4806..54bc697 100644 --- a/team_c_f/lib/storebloc/states/tour.dart +++ b/team_c_f/lib/storebloc/states/tour.dart @@ -1,35 +1,31 @@ import 'package:team_c_f/data/data.dart'; -import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/tour.dart'; -import 'package:team_c_f/servises/tour.dart'; import 'package:team_c_f/storebloc/models/meet.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; class TourState { final int round; - MeetModel? meets; + late MeetsModel meets; late TourModel tour; TourState({required this.round}) { tour = TourModel( tour: Data.tours.where((TourData t) => t.round == round).single); - TourService() - .getMeets(stage: round) - .then((MeetData value) => meets = MeetModel(meet: value)); + meets = MeetsModel( + meet: Data.meets.where((MeetsData m) => m.round == round).single); } - Future copyWith({ + TourState copyWith({ int? round, - MeetModel? meets, + MeetsData? meetsData, TourModel? tour, - }) async { - if (round != null) { - if (await TourService().existsMeets(stage: round)) { - meets = MeetModel( - meet: await TourService().getMeets(stage: round), - ); - } - } + }) { + MeetsModel? meets; + if (meetsData != null) meets = MeetsModel(meet: meetsData); + // if (round != null) + // meets = MeetsModel( + // meet: Data.meets.where((MeetsData m) => m.round == round).single); return TourState.all( round: round ?? this.round, meets: meets ?? this.meets, diff --git a/team_c_f/lib/views/meets.dart b/team_c_f/lib/views/meets.dart new file mode 100644 index 0000000..2341e78 --- /dev/null +++ b/team_c_f/lib/views/meets.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/components/meet.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/storebloc/models/meet.dart'; +import 'package:intl/intl.dart'; + +class ShowMeets extends StatelessWidget { + final MeetsModel meetsModel; + const ShowMeets({Key? key, required this.meetsModel}) : super(key: key); + + @override + Widget build(BuildContext context) { + DateTime deadline = + DateFormat('yyyy-MM-dd HH:mm').parse(meetsModel.deadline); + String day; + switch (deadline.weekday) { + case 1: + day = 'понедельник'; + break; + case 2: + day = 'вторник'; + break; + case 3: + day = 'среду'; + break; + case 4: + day = 'четверг'; + break; + case 5: + day = 'пятницу'; + break; + case 6: + day = 'субботу'; + break; + default: + day = 'воскресенье'; + break; + } + String date = DateFormat('dd.MM').format(deadline); + String time = DateFormat('HH:mm').format(deadline); + return Container( + child: Column( + children: [ + if (!meetsModel.started) + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Дедлайн в ' + day + ' ' + date + ' в ' + time + ' по МСК'), + ), + Wrap( + children: [ + ...meetsModel.meets.map( + (MeetData meetData) => MeetView( + meetData: meetData, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/team_c_f/lib/views/player.dart b/team_c_f/lib/views/player.dart index 5f7bdc2..3e8811e 100644 --- a/team_c_f/lib/views/player.dart +++ b/team_c_f/lib/views/player.dart @@ -39,6 +39,10 @@ class ShowPlayer extends StatelessWidget { } }, child: Card( + color: Colors.cyan[100], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), child: ListTile( leading: CircleAvatar( child: Text(player.prevPosition.toString()), diff --git a/team_c_f/lib/views/team.dart b/team_c_f/lib/views/team.dart index 6e007b3..ef0194c 100644 --- a/team_c_f/lib/views/team.dart +++ b/team_c_f/lib/views/team.dart @@ -13,9 +13,14 @@ class ShowTeam extends StatelessWidget { @override Widget build(BuildContext context) { return Container( + padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Column( children: [ Card( + color: Colors.cyan[200], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), child: Observer( builder: (_) => ListTile( // Информация о команде @@ -25,9 +30,10 @@ class ShowTeam extends StatelessWidget { ), ), title: Text(team.team.name), - trailing: Text(//team.team.points.toString() - showPoints(team.points), - ), + trailing: Text( + //team.team.points.toString() + showPoints(team.points), + ), ), ), ), diff --git a/team_c_f/lib/views/tour.dart b/team_c_f/lib/views/tour.dart index 993304e..1f24f42 100644 --- a/team_c_f/lib/views/tour.dart +++ b/team_c_f/lib/views/tour.dart @@ -1,8 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:team_c_f/storebloc/blocs/schedule.dart'; -import 'package:team_c_f/storebloc/blocs/tour.dart' as tourBloc; import 'package:team_c_f/storebloc/models/tour.dart'; -import 'package:provider/provider.dart'; class ShowTour extends StatelessWidget { final TourModel tour; @@ -10,36 +7,86 @@ class ShowTour extends StatelessWidget { @override Widget build(BuildContext context) { - String title; - double fontSize; - if (tour.name.split(' ').length > 1) { - title = - tour.name.split(' ')[0] + '\n' + tour.name.split(' ')[1] + ' матч'; - fontSize = MediaQuery.of(context).size.width / 20; - } else { - title = tour.name; - fontSize = MediaQuery.of(context).size.width / 15; - } + double size = MediaQuery.of(context).size.width; return Container( padding: const EdgeInsets.all(3.0), child: InkWell( - onTap: () { - // context.read().add( - // tourBloc.TourEvent( - // event: tourBloc.Event.selectTour, stage: tour.stage), - // ); - context.read().add( - ScheduleEvent(event: Event.selectTour, round: tour.stage), - ); - }, - child: CircleAvatar( - radius: MediaQuery.of(context).size.width / 10, - child: Text( - title, - textAlign: TextAlign.center, - maxLines: 2, - style: TextStyle(fontSize: fontSize), - )), + onTap: null, + child: Table( + border: TableBorder( + top: BorderSide( + width: 2, + color: Colors.amber, + ), + right: BorderSide( + width: 2, + color: Colors.amber, + ), + bottom: BorderSide( + width: 2, + color: Colors.amber, + ), + left: BorderSide( + width: 2, + color: Colors.amber, + ), + horizontalInside: BorderSide( + width: 2, + color: Colors.amber, + ), + ), + columnWidths: { + 0: FixedColumnWidth(size / 2.5), + 1: FixedColumnWidth(size / 8), + 2: FixedColumnWidth(size / 2.5), + }, + children: [ + ...tour.result.map( + (List> match) { + String home = match.first.values.single != null + ? match.first.values.single.toString() + : ''; + String away = match.last.values.single != null + ? match.last.values.single.toString() + : ''; + return TableRow( + children: [ + Container( + padding: const EdgeInsets.all(8.0), + child: Text( + match.first.keys.single, + textAlign: TextAlign.center, + ), + color: tour.result.indexOf(match).isEven + ? Colors.cyan[100] + : Colors.cyan[400], + ), + Container( + padding: const EdgeInsets.all(8.0), + child: Text( + home + ':' + away, + textAlign: TextAlign.center, + ), + color: tour.result.indexOf(match).isEven + ? Colors.cyan[100] + : Colors.cyan[400], + ), + Container( + padding: const EdgeInsets.all(8.0), + child: Text( + match.last.keys.single, + textAlign: TextAlign.center, + ), + color: tour.result.indexOf(match).isEven + ? Colors.cyan[100] + : Colors.cyan[400], + ), + ], + ); + }, + ), + ], + ), ), ); } diff --git a/team_c_f/lib/views/touravatar.dart b/team_c_f/lib/views/touravatar.dart new file mode 100644 index 0000000..bb7d19e --- /dev/null +++ b/team_c_f/lib/views/touravatar.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/storebloc/blocs/schedule.dart'; +import 'package:team_c_f/storebloc/blocs/tour.dart' as tourBloc; +import 'package:team_c_f/storebloc/models/tour.dart'; +import 'package:provider/provider.dart'; + +class ShowTourAvatar extends StatelessWidget { + final TourModel tour; + const ShowTourAvatar({Key? key, required this.tour}) : super(key: key); + + @override + Widget build(BuildContext context) { + String title; + double fontSize; + if (tour.name.split(' ').length > 1) { + title = + tour.name.split(' ')[0] + '\n' + tour.name.split(' ')[1] + ' матч'; + fontSize = MediaQuery.of(context).size.width / 20; + } else { + title = tour.name; + fontSize = MediaQuery.of(context).size.width / 15; + } + return Container( + padding: const EdgeInsets.all(3.0), + child: InkWell( + onTap: () { + context.read().add( + ScheduleEvent(event: Event.selectTour, round: tour.stage), + ); + context.read().add( + tourBloc.TourEvent( + event: tourBloc.Event.selectTour, + stage: tour.stage, + ), + ); + }, + child: CircleAvatar( + radius: MediaQuery.of(context).size.width / 10, + child: Text( + title, + textAlign: TextAlign.center, + maxLines: 2, + style: TextStyle(fontSize: fontSize), + )), + ), + ); + } +} diff --git a/team_c_f/pubspec.lock b/team_c_f/pubspec.lock index 81746ef..96f9144 100644 --- a/team_c_f/pubspec.lock +++ b/team_c_f/pubspec.lock @@ -246,13 +246,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" - date_range_picker: - dependency: "direct main" - description: - name: date_range_picker - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.7" fake_async: dependency: transitive description: @@ -328,6 +321,18 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "7.0.0" + flutter_date_pickers: + dependency: "direct main" + description: + name: flutter_date_pickers + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.4" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_mobx: dependency: "direct main" description: diff --git a/team_c_f/pubspec.yaml b/team_c_f/pubspec.yaml index d858c7d..c6ef25b 100644 --- a/team_c_f/pubspec.yaml +++ b/team_c_f/pubspec.yaml @@ -37,7 +37,7 @@ dependencies: bottom_navy_bar: ^6.0.0 provider: ^5.0.0 - date_range_picker: ^1.0.7 + flutter_date_pickers: ^0.2.4 firebase_auth: ^1.0.1 cloud_firestore: ^1.0.3 google_sign_in: ^5.0.1 From 53f0c7e252b0e32da86ca321f5a95cb9db7461fb Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 19 May 2021 18:06:29 +0300 Subject: [PATCH 23/24] =?UTF-8?q?=D0=A0=D1=83=D1=87=D0=BD=D0=BE=D0=B9=20?= =?UTF-8?q?=D0=B4=D0=B5=D0=B4=D0=BB=D0=B0=D0=B9=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/meet.dart | 4 +- team_c_f/lib/components/oneteam.dart | 95 ++++++++++ team_c_f/lib/data/data.dart | 5 +- team_c_f/lib/models/forecast.dart | 22 +-- team_c_f/lib/models/meets.dart | 8 +- team_c_f/lib/pages/home.dart | 7 +- team_c_f/lib/pages/leaveforecast.dart | 72 +++++++ team_c_f/lib/pages/tour.dart | 175 ++++++++++++++++-- team_c_f/lib/servises/data.dart | 18 +- team_c_f/lib/servises/selectmeets.dart | 4 +- team_c_f/lib/servises/tour.dart | 64 ++++--- .../lib/storebloc/blocs/leaveforecast.dart | 41 ++++ team_c_f/lib/storebloc/blocs/schedule.dart | 19 +- team_c_f/lib/storebloc/blocs/tour.dart | 15 +- .../lib/storebloc/models/leaveforecast.dart | 17 ++ .../lib/storebloc/states/leaveforecast.dart | 43 +++++ team_c_f/lib/storebloc/states/schedule.dart | 3 +- team_c_f/lib/storebloc/states/tour.dart | 16 +- team_c_f/lib/views/touravatar.dart | 7 +- 19 files changed, 554 insertions(+), 81 deletions(-) create mode 100644 team_c_f/lib/components/oneteam.dart create mode 100644 team_c_f/lib/pages/leaveforecast.dart create mode 100644 team_c_f/lib/storebloc/blocs/leaveforecast.dart create mode 100644 team_c_f/lib/storebloc/models/leaveforecast.dart create mode 100644 team_c_f/lib/storebloc/states/leaveforecast.dart diff --git a/team_c_f/lib/components/meet.dart b/team_c_f/lib/components/meet.dart index fc440bd..398f63a 100644 --- a/team_c_f/lib/components/meet.dart +++ b/team_c_f/lib/components/meet.dart @@ -9,7 +9,7 @@ class MeetView extends StatelessWidget { @override Widget build(BuildContext context) { DateTime date = DateFormat('yyyy-MM-dd HH:mm').parse(meetData.date); - String status = meetData == 'Не начат' + String status = meetData.status == 'Не начат' ? date.day == DateTime.now().day ? DateFormat('HH:mm').format(date) : DateFormat('dd.MM').format(date) @@ -18,7 +18,7 @@ class MeetView extends StatelessWidget { padding: const EdgeInsets.all(2.0), child: Container( padding: const EdgeInsets.all(8.0), - color: meetData.started ? Colors.green[100] : Colors.yellow[200], + color: meetData.started ? Colors.green[100] : Colors.yellow[300], width: MediaQuery.of(context).size.width / 2 - 15, child: Column( children: [ diff --git a/team_c_f/lib/components/oneteam.dart b/team_c_f/lib/components/oneteam.dart new file mode 100644 index 0000000..2897e59 --- /dev/null +++ b/team_c_f/lib/components/oneteam.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:team_c_f/storebloc/blocs/leaveforecast.dart'; +import 'package:team_c_f/storebloc/models/leaveforecast.dart'; +import 'package:provider/provider.dart'; + +class OneTeamView extends StatelessWidget { + final LeaveForecastModel forecast; + OneTeamView({Key? key, required this.forecast}) : super(key: key); + + final List numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + @override + Widget build(BuildContext context) { + LeaveForecastBloc bloc = context.read(); + double size = MediaQuery.of(context).size.width; + return Card( + color: Colors.blue[400], + child: Table( + defaultVerticalAlignment: TableCellVerticalAlignment.middle, + columnWidths: { + 0: FixedColumnWidth(size / 7), + 1: FixedColumnWidth(size / 3), + 2: FixedColumnWidth(size / 11), + 3: FixedColumnWidth(size / 40), + 4: FixedColumnWidth(size / 11), + 5: FixedColumnWidth(size / 3), + }, + children: [ + TableRow( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Text(forecast.date), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + forecast.teams.first, + textAlign: TextAlign.right, + ), + ), + DropdownButton( + value: forecast.home, + onChanged: (i) { + bloc.add( + LeaveForecastEvent( + event: Event.changeValue, + position: true, + index: bloc.state.meets.indexOf(forecast), + newValue: i), + ); + }, + items: [ + ...numbers.map>( + (int number) => DropdownMenuItem( + child: Text(number.toString()), + value: number, + ), + ), + ], + ), + Text(':'), + DropdownButton( + value: forecast.away, + onChanged: (i) { + bloc.add( + LeaveForecastEvent( + event: Event.changeValue, + position: false, + index: bloc.state.meets.indexOf(forecast), + newValue: i), + ); + }, + items: [ + ...numbers.map>( + (int number) => DropdownMenuItem( + child: Text(number.toString()), + value: number, + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + forecast.teams.last, + textAlign: TextAlign.left, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/team_c_f/lib/data/data.dart b/team_c_f/lib/data/data.dart index 70c1352..aad02b8 100644 --- a/team_c_f/lib/data/data.dart +++ b/team_c_f/lib/data/data.dart @@ -33,6 +33,7 @@ class Data with ChangeNotifier { static late List teams; static late List tours; static late List meets; + static late List names = []; static void sortTour() { tours.sort((TourData a, b) => @@ -98,10 +99,6 @@ class Data with ChangeNotifier { ); // указание текущей позиции команды } - static Future getMeets(int stage) async { - return TourService().getMeets(stage: stage); - } - static void sortTeam({required List teams}) { teams.sort((TeamData a, b) => (b.goals - b.missed) .compareTo(a.goals - a.missed)); // сортировка команд по разнице забитых diff --git a/team_c_f/lib/models/forecast.dart b/team_c_f/lib/models/forecast.dart index 74fcdca..71d62d5 100644 --- a/team_c_f/lib/models/forecast.dart +++ b/team_c_f/lib/models/forecast.dart @@ -1,21 +1,16 @@ class ForecastData { + late String docId; final String uid; - final List rate; + final List rate; final String? team; - final String stage; + final int round; int result = 0; - // - идентификатор игрока, - // - лист прогнозов, - // - название тура, - // - название команды, - // - результат. - ForecastData({ required this.uid, required this.rate, required this.team, - required this.stage, + required this.round, }); Map toMap() { @@ -23,19 +18,20 @@ class ForecastData { 'UserId': uid, 'Rate': rate, 'Team': team, - 'Stage': stage, + 'Round': round, 'Result': result, }; } - factory ForecastData.fromMap({required Map data}) { + factory ForecastData.fromMap({required Map data, required String docId}) { ForecastData f = ForecastData( uid: data['UserId'], - rate: data['Rate'], + rate: data['Rate'].cast(), team: data['Team'], - stage: data['Stage'], + round: data['Round'], ); f.result = data['Result']; + f.docId = docId; return f; } } diff --git a/team_c_f/lib/models/meets.dart b/team_c_f/lib/models/meets.dart index 8397b33..d81b500 100644 --- a/team_c_f/lib/models/meets.dart +++ b/team_c_f/lib/models/meets.dart @@ -1,11 +1,11 @@ import 'meet.dart'; class MeetsData { - late String uid; + late String docId; final int round; final List meets; final String deadline; - final bool started; + late bool started; MeetsData({ required this.round, @@ -15,7 +15,7 @@ class MeetsData { }); factory MeetsData.fromMap( - {required Map data, required String uid}) { + {required Map data, required String docId}) { List a = []; if (data['Meets'].isNotEmpty) a.addAll( @@ -33,7 +33,7 @@ class MeetsData { deadline: data['Deadline'], started: data['Started'], ); - meets.uid = uid; + meets.docId = docId; return meets; } diff --git a/team_c_f/lib/pages/home.dart b/team_c_f/lib/pages/home.dart index 0f94221..61ca13c 100644 --- a/team_c_f/lib/pages/home.dart +++ b/team_c_f/lib/pages/home.dart @@ -3,12 +3,14 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:provider/provider.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/pages/schedule.dart'; import 'package:team_c_f/pages/team.dart'; import 'package:team_c_f/pages/tour.dart'; import 'package:team_c_f/storebloc/blocs/myteam.dart'; import 'package:team_c_f/storebloc/blocs/schedule.dart'; import 'package:team_c_f/storebloc/blocs/tour.dart'; +import 'package:team_c_f/storebloc/models/meet.dart'; import 'package:team_c_f/storebloc/states/myteam.dart'; import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:team_c_f/store/home/home.dart'; @@ -36,7 +38,10 @@ class HomePage extends StatelessWidget { ), BlocProvider( create: (BuildContext context) => TourBloc( - TourState(round: Data.currentTour.round), + TourState( + round: Data.currentTour.round, + uid: context.read().userId, + ), ), ), ], diff --git a/team_c_f/lib/pages/leaveforecast.dart b/team_c_f/lib/pages/leaveforecast.dart new file mode 100644 index 0000000..bf96ec3 --- /dev/null +++ b/team_c_f/lib/pages/leaveforecast.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/components/oneteam.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/tour.dart'; +import 'package:team_c_f/storebloc/blocs/leaveforecast.dart'; +import 'package:team_c_f/storebloc/models/leaveforecast.dart'; +import 'package:team_c_f/storebloc/states/leaveforecast.dart'; + +class LeaveForecastPage extends StatelessWidget { + //final MeetsData meetsData; + LeaveForecastPage({ + Key? key, + //required this.meetsData, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + bloc: context.watch(), + builder: (context, state) => SafeArea( + child: Scaffold( + appBar: AppBar( + title: Text( + 'Прогноз на ' + + Data.tours + .where((TourData t) => t.round == state.round) + .single + .name! + + ((Data.tours + .where((TourData t) => t.round == state.round) + .single + .name! + .length) < + 3 + ? ' тур' + : ''), + ), + ), + body: Center( + child: Column( + children: [ + Expanded( + child: ListView( + children: [ + ...state.meets + .map( + (LeaveForecastModel forecast) => OneTeamView( + forecast: forecast, + ), + ) + .toList(), + ], + ), + ), + ElevatedButton( + onPressed: () { + Navigator.pop( + context, + state, + ); + }, + child: Text('Оставить прогноз'), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/team_c_f/lib/pages/tour.dart b/team_c_f/lib/pages/tour.dart index f7b97ba..c1ee38c 100644 --- a/team_c_f/lib/pages/tour.dart +++ b/team_c_f/lib/pages/tour.dart @@ -1,9 +1,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; +import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/forecast.dart'; +import 'package:team_c_f/models/meets.dart'; +import 'package:team_c_f/models/player.dart'; +import 'package:team_c_f/pages/leaveforecast.dart'; import 'package:team_c_f/pages/selectmeets.dart'; +import 'package:team_c_f/servises/tour.dart'; +import 'package:team_c_f/store/login/login.dart'; +import 'package:team_c_f/storebloc/blocs/leaveforecast.dart' as leave; import 'package:team_c_f/storebloc/blocs/schedule.dart' as schedule; import 'package:team_c_f/storebloc/blocs/tour.dart'; +import 'package:team_c_f/storebloc/models/leaveforecast.dart'; +import 'package:team_c_f/storebloc/states/leaveforecast.dart'; import 'package:team_c_f/storebloc/states/tour.dart'; import 'package:team_c_f/views/meets.dart'; import 'package:team_c_f/views/tour.dart'; @@ -22,16 +33,72 @@ class TourPage extends StatelessWidget { child: Center( child: Column( children: [ - if (back) - TextButton( - onPressed: () { - context.read().add( - schedule.ScheduleEvent( - event: schedule.Event.unselectTour), - ); - }, - child: Text('Назад'), - ), + back + ? TextButton( + onPressed: () { + context.read().add( + schedule.ScheduleEvent( + event: schedule.Event.unselectTour), + ); + }, + child: Text( + 'Назад', + textAlign: TextAlign.center, + ), + ) + : Card( + color: Colors.yellow[300], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20)), + child: Container( + width: MediaQuery.of(context).size.width - 20, + child: Column( + children: [ + TextButton( + onPressed: () { + bloc.add( + TourEvent(event: Event.showListAbsense)); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(8.0), + child: Text( + 'Список неявок', + textAlign: TextAlign.center, + ), + ), + ), + state.size + ? Container( + child: Column( + children: [ + ...Data.players + .where( + (player) => player.team != '') + .where((player) => Data.names.every( + (leave) => leave != player.uid)) + .map( + (player) => Padding( + padding: + const EdgeInsets.all(8.0), + child: Text(player.name), + ), + ), + ], + ), + ) + : SizedBox( + height: 0, + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'Матчи ${state.tour.name} ${state.tour.name.length < 3 ? 'тура' : ''}'), + ), state.meets.meets.isNotEmpty ? Column( children: [ @@ -41,10 +108,82 @@ class TourPage extends StatelessWidget { meetsModel: state.meets, ), ), - TextButton( - onPressed: null, - child: Text('Оставить прогноз'), - ), + if (!state.meets.started) + TextButton( + onPressed: () async { + ForecastData? oldForecast; + if (Data.names.isNotEmpty) + oldForecast = await TourService().getForecast( + uid: context.read().userId, + round: state.round, + ); + await TourService() + .enableTour(round: state.tour.stage) + ? Navigator.of(context) + .push( + MaterialPageRoute( + builder: (context) => BlocProvider< + leave.LeaveForecastBloc>( + create: (_) => + leave.LeaveForecastBloc( + LeaveForecastState( + meetsData: Data.meets + .where((MeetsData m) => + m.round == state.round) + .single, + forecast: oldForecast, + ), + ), + child: LeaveForecastPage(), + ), + ), + ) + .then( + (LeaveForecastState? result) { + if (result != null) { + List rate = []; + PlayerData me = Data.players + .where((PlayerData p) => + p.uid == + context + .read() + .userId) + .single; + ForecastData forecast = + ForecastData( + uid: me.uid, + team: me.team, + round: result.round, + rate: rate, + ); + result.meets.forEach( + (LeaveForecastModel model) { + rate.addAll( + [model.home, model.away]); + }, + ); + if (oldForecast != null) { + forecast.docId = + oldForecast.docId; + TourService().updateForecast( + forecast: forecast, + ); + } else + TourService().leaveForecast( + forecast: forecast, + ); + bloc.add( + TourEvent( + event: Event.makeForecast, + ), + ); + } + }, + ) + : Fluttertoast.showToast( + msg: 'Приём прогнозов закрыт'); + }, + child: Text('Мой прогноз')), ], ) : TextButton( @@ -53,7 +192,7 @@ class TourPage extends StatelessWidget { .push( MaterialPageRoute( builder: (context) => - SelectMeetsPage(round: bloc.state.round), + SelectMeetsPage(round: state.round), ), ) .then( @@ -65,6 +204,12 @@ class TourPage extends StatelessWidget { child: Text('Выбрать матчи'), ), ShowTour(tour: state.tour), + ElevatedButton( + onPressed: (){ + TourService().closeForecasting(round: state.tour.stage); + }, + child: Text('Закрыть приём прогнозов'), + ), ], ), ), diff --git a/team_c_f/lib/servises/data.dart b/team_c_f/lib/servises/data.dart index 6c72d9d..ef8207a 100644 --- a/team_c_f/lib/servises/data.dart +++ b/team_c_f/lib/servises/data.dart @@ -1,6 +1,7 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:team_c_f/models/currenttour.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/forecast.dart'; import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/player.dart'; import 'package:team_c_f/models/team.dart'; @@ -17,6 +18,8 @@ class DataService { FirebaseFirestore.instance.collection('schedule'); final CollectionReference _meetsCollection = FirebaseFirestore.instance.collection('meets'); + final CollectionReference _forecastsCollection = + FirebaseFirestore.instance.collection('forecasts'); Future initData() async { Data.currentTour = await getCurrentTour(); @@ -24,9 +27,22 @@ class DataService { Data.teams = await getTeams(); Data.tours = await getTours(); Data.meets = await getMeets(); + Data.names = await getUidLeftForecast(); return true; } + Future> getUidLeftForecast() { + int round = Data.currentTour.round; + if (Data.meets.where((element) => element.round == round).single.started) + round++; + return _forecastsCollection.where('Round', isEqualTo: round).get().then( + (QuerySnapshot response) => response.docs + .map((QueryDocumentSnapshot doc) => + ForecastData.fromMap(data: doc.data(), docId: doc.id).uid) + .toList(), + ); + } + Future getCurrentTour() { return _currentTourCollection.get().then( (QuerySnapshot response) => CurrentTourData.fromMap( @@ -79,7 +95,7 @@ class DataService { (QuerySnapshot response) => response.docs .map( (QueryDocumentSnapshot doc) => - MeetsData.fromMap(data: doc.data(), uid: doc.id), + MeetsData.fromMap(data: doc.data(), docId: doc.id), ) .toList(), ); diff --git a/team_c_f/lib/servises/selectmeets.dart b/team_c_f/lib/servises/selectmeets.dart index 90c1fbf..cd21159 100644 --- a/team_c_f/lib/servises/selectmeets.dart +++ b/team_c_f/lib/servises/selectmeets.dart @@ -8,9 +8,9 @@ class SelectMeetsService { void cteateMeet({required MeetsData meet}) { MeetsData current = Data.meets.where((element) => element.round == meet.round).single; - meet.uid = current.uid; + meet.docId = current.docId; Data.meets.remove(current); Data.meets.add(meet); - _meetsCollection.doc(meet.uid).update(meet.toMap()); + _meetsCollection.doc(meet.docId).update(meet.toMap()); } } diff --git a/team_c_f/lib/servises/tour.dart b/team_c_f/lib/servises/tour.dart index 5db6389..2158695 100644 --- a/team_c_f/lib/servises/tour.dart +++ b/team_c_f/lib/servises/tour.dart @@ -1,33 +1,53 @@ import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:team_c_f/models/forecast.dart'; import 'package:team_c_f/models/meets.dart'; class TourService { + final CollectionReference _forecastsCollection = + FirebaseFirestore.instance.collection('forecasts'); final CollectionReference _meetsCollection = FirebaseFirestore.instance.collection('meets'); - Future existsMeets({required int stage}) async { - DocumentReference doc = await _meetsCollection.add({'Test': 'test'}); - QuerySnapshot snapshot = await _meetsCollection.get(); - if (snapshot.docs.length != 1) { - _meetsCollection.doc(doc.id).delete(); - return (await _meetsCollection.where('Round', isEqualTo: stage).get()) - .docs - .length == - 1; - } else { - _meetsCollection.doc(doc.id).delete(); - return false; - } + void leaveForecast({required ForecastData forecast}) { + _forecastsCollection.add(forecast.toMap()); } - Future getMeets({required int stage}) async { - QuerySnapshot response = - await _meetsCollection.where('Round', isEqualTo: stage).get(); - return response.docs.length != 0 - ? MeetsData.fromMap( - data: response.docs.single.data(), - uid: response.docs.single.id, - ) - : null; + void updateForecast({required ForecastData forecast}) { + _forecastsCollection.doc(forecast.docId).update(forecast.toMap()); + } + + Future getForecast({required String uid, required int round}) { + return _forecastsCollection + .where('Round', isEqualTo: round) + .where('UserId', isEqualTo: uid) + .get() + .then( + (QuerySnapshot response) => response.docs.length == 1 + ? ForecastData.fromMap( + data: response.docs.single.data(), + docId: response.docs.single.id, + ) + : null, + ); + } + + Future enableTour({required int round}) { + return _meetsCollection + .where('Round', isEqualTo: round) + .get() + .then((QuerySnapshot response) => !MeetsData.fromMap( + data: response.docs.single.data(), + docId: response.docs.single.id, + ).started); + } + + Future closeForecasting({required int round}) async { + QueryDocumentSnapshot doc = + (await _meetsCollection.where('Round', isEqualTo: round).get()) + .docs + .single; + MeetsData meets = MeetsData.fromMap(data: doc.data(), docId: doc.id); + meets.started = true; + _meetsCollection.doc(doc.id).update(meets.toMap()); } } diff --git a/team_c_f/lib/storebloc/blocs/leaveforecast.dart b/team_c_f/lib/storebloc/blocs/leaveforecast.dart new file mode 100644 index 0000000..e52e3f4 --- /dev/null +++ b/team_c_f/lib/storebloc/blocs/leaveforecast.dart @@ -0,0 +1,41 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:team_c_f/storebloc/states/leaveforecast.dart'; + +class LeaveForecastEvent { + final bool? position; + final int? index; + final int? newValue; + final Event event; + + LeaveForecastEvent({ + this.position, + this.index, + this.newValue, + required this.event, + }); +} + +enum Event { + changeValue, +} + +class LeaveForecastBloc extends Bloc { + LeaveForecastBloc(LeaveForecastState initialState) : super(initialState); + + @override + Stream mapEventToState(LeaveForecastEvent event) async* { + switch (event.event) { + case Event.changeValue: + if (event.index != null && + event.newValue != null && + event.position != null) { + if (event.position!) + state.meets[event.index!].home = event.newValue!; + else + state.meets[event.index!].away = event.newValue!; + yield state.copyWith(meets: state.meets); + } + break; + } + } +} diff --git a/team_c_f/lib/storebloc/blocs/schedule.dart b/team_c_f/lib/storebloc/blocs/schedule.dart index 7f3b2f0..c724cd4 100644 --- a/team_c_f/lib/storebloc/blocs/schedule.dart +++ b/team_c_f/lib/storebloc/blocs/schedule.dart @@ -1,16 +1,19 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/storebloc/blocs/tour.dart'; +import 'package:team_c_f/storebloc/models/meet.dart'; import 'package:team_c_f/storebloc/states/schedule.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; import 'package:team_c_f/storebloc/states/tour.dart'; class ScheduleEvent { int? round; + String? uid; final Event event; - ScheduleEvent({required this.event, this.round}); + ScheduleEvent({required this.event, this.round, this.uid}); } enum Event { @@ -36,10 +39,20 @@ class ScheduleBloc extends Bloc { break; case Event.selectTour: state.tourBloc = TourBloc( - TourState(round: event.round!), + TourState( + round: event.round!, + uid: event.uid!, + // meets: MeetsModel( + // meet: Data.meets + // .where((MeetsData m) => m.round == event.round) + // .single), + ), ); yield state.copyWith( - tourSelected: true, round: event.round!, tourBloc: state.tourBloc); + tourSelected: true, + round: event.round!, + tourBloc: state.tourBloc, + ); break; case Event.unselectTour: yield state.copyWith(tourSelected: false); diff --git a/team_c_f/lib/storebloc/blocs/tour.dart b/team_c_f/lib/storebloc/blocs/tour.dart index e79e51e..31c5572 100644 --- a/team_c_f/lib/storebloc/blocs/tour.dart +++ b/team_c_f/lib/storebloc/blocs/tour.dart @@ -10,6 +10,7 @@ class TourEvent { } enum Event { + showListAbsense, makeForecast, selectMeets, selectTour, @@ -21,8 +22,11 @@ class TourBloc extends Bloc { @override Stream mapEventToState(TourEvent event) async* { switch (event.event) { + case Event.showListAbsense: + yield state.copyWith(size: !state.size); + break; case Event.makeForecast: - yield state; + yield state.copyWith(); break; case Event.selectMeets: Data().refreshData(); @@ -31,10 +35,11 @@ class TourBloc extends Bloc { case Event.selectTour: if (event.stage != null) { yield state.copyWith( - round: event.stage, - meetsData: Data.meets - .where((element) => element.round == event.stage) - .single); + round: event.stage, + // meetsData: Data.meets + // .where((element) => element.round == event.stage) + // .single, + ); } break; } diff --git a/team_c_f/lib/storebloc/models/leaveforecast.dart b/team_c_f/lib/storebloc/models/leaveforecast.dart new file mode 100644 index 0000000..968977f --- /dev/null +++ b/team_c_f/lib/storebloc/models/leaveforecast.dart @@ -0,0 +1,17 @@ +import 'package:team_c_f/models/meet.dart'; +import 'package:intl/intl.dart'; + +class LeaveForecastModel { + late String date; + late int home; + late int away; + late List teams = []; + + LeaveForecastModel({required MeetData meet, List? goal}) { + date = DateFormat('dd.MM') + .format(DateFormat('yyyy-MM-dd HH:mm').parse(meet.date)); + home = goal != null ? goal[0] : meet.score.first; + away = goal != null ? goal[1] : meet.score.last; + teams.addAll([...meet.team]); + } +} diff --git a/team_c_f/lib/storebloc/states/leaveforecast.dart b/team_c_f/lib/storebloc/states/leaveforecast.dart new file mode 100644 index 0000000..4f303e6 --- /dev/null +++ b/team_c_f/lib/storebloc/states/leaveforecast.dart @@ -0,0 +1,43 @@ +import 'package:team_c_f/models/forecast.dart'; +import 'package:team_c_f/models/meet.dart'; +import 'package:team_c_f/models/meets.dart'; +import 'package:team_c_f/storebloc/models/leaveforecast.dart'; + +class LeaveForecastState { + late int round; + late List meets = []; + + LeaveForecastState({ + required MeetsData meetsData, + ForecastData? forecast, + }) { + round = meetsData.round; + meets.addAll([ + ...meetsData.meets.map( + (MeetData meet) => LeaveForecastModel( + meet: meet, + goal: forecast != null + ? [ + forecast.rate[meetsData.meets.indexOf(meet) * 2], + forecast.rate[meetsData.meets.indexOf(meet) * 2 + 1] + ] + : null, + ), + ), + ]); + } + + LeaveForecastState copyWith({ + int? round, + List? meets, + }) => + LeaveForecastState.all( + round: round ?? this.round, + meets: meets ?? this.meets, + ); + + LeaveForecastState.all({ + required this.round, + required this.meets, + }); +} diff --git a/team_c_f/lib/storebloc/states/schedule.dart b/team_c_f/lib/storebloc/states/schedule.dart index a1f7dc4..458b834 100644 --- a/team_c_f/lib/storebloc/states/schedule.dart +++ b/team_c_f/lib/storebloc/states/schedule.dart @@ -16,7 +16,6 @@ class ScheduleState { ScheduleState copyWith({ List? tours, - //MeetsModel? meets, int? nameTour, bool? tourSelected, int? round, @@ -26,7 +25,7 @@ class ScheduleState { tours: tours ?? this.tours, tourSelected: tourSelected ?? this.tourSelected, round: round ?? this.round, - tourBloc: tourBloc ?? tourBloc, + tourBloc: tourBloc ?? this.tourBloc, ); } diff --git a/team_c_f/lib/storebloc/states/tour.dart b/team_c_f/lib/storebloc/states/tour.dart index 54bc697..b8f903b 100644 --- a/team_c_f/lib/storebloc/states/tour.dart +++ b/team_c_f/lib/storebloc/states/tour.dart @@ -1,4 +1,5 @@ import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/models/forecast.dart'; import 'package:team_c_f/models/meets.dart'; import 'package:team_c_f/models/tour.dart'; import 'package:team_c_f/storebloc/models/meet.dart'; @@ -8,28 +9,30 @@ class TourState { final int round; late MeetsModel meets; late TourModel tour; + late bool size = false; - TourState({required this.round}) { + TourState({required this.round, required String uid}) { tour = TourModel( tour: Data.tours.where((TourData t) => t.round == round).single); meets = MeetsModel( meet: Data.meets.where((MeetsData m) => m.round == round).single); + // TourService() + // .getForecast(uid: uid, round: round) + // .then((ForecastData? response) => forecast = response); } TourState copyWith({ int? round, MeetsData? meetsData, TourModel? tour, + bool? size, }) { - MeetsModel? meets; - if (meetsData != null) meets = MeetsModel(meet: meetsData); - // if (round != null) - // meets = MeetsModel( - // meet: Data.meets.where((MeetsData m) => m.round == round).single); + MeetsModel? meets = meetsData != null ? MeetsModel(meet: meetsData) : null; return TourState.all( round: round ?? this.round, meets: meets ?? this.meets, tour: tour ?? this.tour, + size: size ?? this.size, ); } @@ -37,5 +40,6 @@ class TourState { required this.round, required this.meets, required this.tour, + required this.size, }); } diff --git a/team_c_f/lib/views/touravatar.dart b/team_c_f/lib/views/touravatar.dart index bb7d19e..5cbecd2 100644 --- a/team_c_f/lib/views/touravatar.dart +++ b/team_c_f/lib/views/touravatar.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:team_c_f/store/login/login.dart'; import 'package:team_c_f/storebloc/blocs/schedule.dart'; import 'package:team_c_f/storebloc/blocs/tour.dart' as tourBloc; import 'package:team_c_f/storebloc/models/tour.dart'; @@ -25,7 +26,11 @@ class ShowTourAvatar extends StatelessWidget { child: InkWell( onTap: () { context.read().add( - ScheduleEvent(event: Event.selectTour, round: tour.stage), + ScheduleEvent( + event: Event.selectTour, + round: tour.stage, + uid: context.read().userId, + ), ); context.read().add( tourBloc.TourEvent( From 3e0d296b9af44ca61fd3d256d65e78b72d60a168 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Wed, 19 May 2021 19:42:15 +0300 Subject: [PATCH 24/24] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=D0=B8=D0=B4=20=D0=BC=D0=B0=D1=82=D1=87=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BD?= =?UTF-8?q?=D0=BE=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- team_c_f/lib/components/meet.dart | 31 ++++------ team_c_f/lib/pages/tour.dart | 4 +- team_c_f/lib/storebloc/blocs/tour.dart | 7 +++ team_c_f/lib/views/tour.dart | 86 +++++++++++++------------- 4 files changed, 63 insertions(+), 65 deletions(-) diff --git a/team_c_f/lib/components/meet.dart b/team_c_f/lib/components/meet.dart index 398f63a..dd9de58 100644 --- a/team_c_f/lib/components/meet.dart +++ b/team_c_f/lib/components/meet.dart @@ -14,39 +14,32 @@ class MeetView extends StatelessWidget { ? DateFormat('HH:mm').format(date) : DateFormat('dd.MM').format(date) : meetData.status; + String score = meetData.started + ? '${meetData.score.first}:${meetData.score.last}' + : '-'; + double width = MediaQuery.of(context).size.width; return Padding( padding: const EdgeInsets.all(2.0), child: Container( padding: const EdgeInsets.all(8.0), color: meetData.started ? Colors.green[100] : Colors.yellow[300], - width: MediaQuery.of(context).size.width / 2 - 15, + width: width - 15, child: Column( children: [ - Text(status), Table( columnWidths: { - 0: IntrinsicColumnWidth(flex: 0.9), - 1: IntrinsicColumnWidth(flex: 0.1) + 0: FixedColumnWidth(width/6.5), + 1: FixedColumnWidth(width/3), + 2: FixedColumnWidth(width/10), + 3: FixedColumnWidth(width/3) }, children: [ TableRow( children: [ - Text(meetData.team.first), - if (!meetData.started) - Text( - meetData.score.first.toString(), - textAlign: TextAlign.right, - ), - ], - ), - TableRow( - children: [ + Text(status, textAlign: TextAlign.center), + Text(meetData.team.first, textAlign: TextAlign.right), + Text(score, textAlign: TextAlign.center), Text(meetData.team.last), - if (!meetData.started) - Text( - meetData.score.last.toString(), - textAlign: TextAlign.right, - ), ], ), ], diff --git a/team_c_f/lib/pages/tour.dart b/team_c_f/lib/pages/tour.dart index c1ee38c..607481f 100644 --- a/team_c_f/lib/pages/tour.dart +++ b/team_c_f/lib/pages/tour.dart @@ -205,8 +205,8 @@ class TourPage extends StatelessWidget { ), ShowTour(tour: state.tour), ElevatedButton( - onPressed: (){ - TourService().closeForecasting(round: state.tour.stage); + onPressed: () { + bloc.add(TourEvent(event: Event.closeForecasting)); }, child: Text('Закрыть приём прогнозов'), ), diff --git a/team_c_f/lib/storebloc/blocs/tour.dart b/team_c_f/lib/storebloc/blocs/tour.dart index 31c5572..95807a6 100644 --- a/team_c_f/lib/storebloc/blocs/tour.dart +++ b/team_c_f/lib/storebloc/blocs/tour.dart @@ -1,5 +1,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:team_c_f/data/data.dart'; +import 'package:team_c_f/servises/tour.dart'; import 'package:team_c_f/storebloc/states/tour.dart'; class TourEvent { @@ -10,6 +11,7 @@ class TourEvent { } enum Event { + closeForecasting, showListAbsense, makeForecast, selectMeets, @@ -22,6 +24,11 @@ class TourBloc extends Bloc { @override Stream mapEventToState(TourEvent event) async* { switch (event.event) { + case Event.closeForecasting: + TourService().closeForecasting(round: state.tour.stage); + Data().refreshData(); + yield state.copyWith(meetsData: Data.meets.where((m) => m.round == state.tour.stage).single); + break; case Event.showListAbsense: yield state.copyWith(size: !state.size); break; diff --git a/team_c_f/lib/views/tour.dart b/team_c_f/lib/views/tour.dart index 1f24f42..e2134d2 100644 --- a/team_c_f/lib/views/tour.dart +++ b/team_c_f/lib/views/tour.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:team_c_f/storebloc/models/tour.dart'; class ShowTour extends StatelessWidget { @@ -10,46 +11,44 @@ class ShowTour extends StatelessWidget { double size = MediaQuery.of(context).size.width; return Container( padding: const EdgeInsets.all(3.0), - child: InkWell( - onTap: null, - child: Table( - border: TableBorder( - top: BorderSide( - width: 2, - color: Colors.amber, - ), - right: BorderSide( - width: 2, - color: Colors.amber, - ), - bottom: BorderSide( - width: 2, - color: Colors.amber, - ), - left: BorderSide( - width: 2, - color: Colors.amber, - ), - horizontalInside: BorderSide( - width: 2, - color: Colors.amber, - ), + child: Table( + border: TableBorder( + top: BorderSide( + width: 2, + color: Colors.amber, ), - columnWidths: { - 0: FixedColumnWidth(size / 2.5), - 1: FixedColumnWidth(size / 8), - 2: FixedColumnWidth(size / 2.5), - }, - children: [ - ...tour.result.map( - (List> match) { - String home = match.first.values.single != null - ? match.first.values.single.toString() - : ''; - String away = match.last.values.single != null - ? match.last.values.single.toString() - : ''; - return TableRow( + right: BorderSide( + width: 2, + color: Colors.amber, + ), + bottom: BorderSide( + width: 2, + color: Colors.amber, + ), + left: BorderSide( + width: 2, + color: Colors.amber, + ), + horizontalInside: BorderSide( + width: 2, + color: Colors.amber, + ), + ), + columnWidths: { + 0: FixedColumnWidth(size / 2.5), + 1: FixedColumnWidth(size / 8), + 2: FixedColumnWidth(size / 2.5), + }, + children: [ + ...tour.result.map( + (List> match) { + String home = match.first.values.single != null + ? match.first.values.single.toString() + : ''; + String away = match.last.values.single != null + ? match.last.values.single.toString() + : ''; + return TableRow( children: [ Container( padding: const EdgeInsets.all(8.0), @@ -82,11 +81,10 @@ class ShowTour extends StatelessWidget { : Colors.cyan[400], ), ], - ); - }, - ), - ], - ), + ); + }, + ), + ], ), ); }