feat: new team member selection
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"@@locale": "de",
|
"@@locale": "de",
|
||||||
|
"add_team": "Team hinzufügen",
|
||||||
"all_players": "Alle Spieler:innen",
|
"all_players": "Alle Spieler:innen",
|
||||||
"all_players_selected": "Alle Spieler:innen ausgewählt",
|
"all_players_selected": "Alle Spieler:innen ausgewählt",
|
||||||
"amount_of_matches": "Anzahl der Spiele",
|
"amount_of_matches": "Anzahl der Spiele",
|
||||||
@@ -50,7 +51,6 @@
|
|||||||
"edit_game": "Spielvorlage bearbeiten",
|
"edit_game": "Spielvorlage bearbeiten",
|
||||||
"edit_group": "Gruppe bearbeiten",
|
"edit_group": "Gruppe bearbeiten",
|
||||||
"edit_match": "Gruppe bearbeiten",
|
"edit_match": "Gruppe bearbeiten",
|
||||||
"edit_members": "Mitglieder bearbeiten",
|
|
||||||
"enter_points": "Punkte eingeben",
|
"enter_points": "Punkte eingeben",
|
||||||
"enter_results": "Ergebnisse eintragen",
|
"enter_results": "Ergebnisse eintragen",
|
||||||
"error_creating_group": "Fehler beim Erstellen der Gruppe, bitte erneut versuchen",
|
"error_creating_group": "Fehler beim Erstellen der Gruppe, bitte erneut versuchen",
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
"live_edit_mode": "Live-Bearbeitungsmodus",
|
"live_edit_mode": "Live-Bearbeitungsmodus",
|
||||||
"loser": "Verlierer:in",
|
"loser": "Verlierer:in",
|
||||||
"lowest_score": "Niedrigste Punkte",
|
"lowest_score": "Niedrigste Punkte",
|
||||||
|
"manage_members": "Mitglieder bearbeiten",
|
||||||
"match_in_progress": "Spiel läuft...",
|
"match_in_progress": "Spiel läuft...",
|
||||||
"match_name": "Spieltitel",
|
"match_name": "Spieltitel",
|
||||||
"match_profile": "Spielprofil",
|
"match_profile": "Spielprofil",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
|
"add_team": "Add Team",
|
||||||
"all_players": "All players",
|
"all_players": "All players",
|
||||||
"all_players_selected": "All players selected",
|
"all_players_selected": "All players selected",
|
||||||
"amount_of_matches": "Amount of Matches",
|
"amount_of_matches": "Amount of Matches",
|
||||||
@@ -50,7 +51,6 @@
|
|||||||
"edit_game": "Edit Game",
|
"edit_game": "Edit Game",
|
||||||
"edit_group": "Edit Group",
|
"edit_group": "Edit Group",
|
||||||
"edit_match": "Edit Match",
|
"edit_match": "Edit Match",
|
||||||
"edit_members": "Edit Members",
|
|
||||||
"enter_points": "Enter points",
|
"enter_points": "Enter points",
|
||||||
"enter_results": "Enter Results",
|
"enter_results": "Enter Results",
|
||||||
"error_creating_group": "Error while creating group, please try again",
|
"error_creating_group": "Error while creating group, please try again",
|
||||||
@@ -81,6 +81,7 @@
|
|||||||
"live_edit_mode": "Live Edit Mode",
|
"live_edit_mode": "Live Edit Mode",
|
||||||
"loser": "Loser",
|
"loser": "Loser",
|
||||||
"lowest_score": "Lowest Score",
|
"lowest_score": "Lowest Score",
|
||||||
|
"manage_members": "Manage Members",
|
||||||
"match_in_progress": "Match in progress...",
|
"match_in_progress": "Match in progress...",
|
||||||
"match_name": "Match name",
|
"match_name": "Match name",
|
||||||
"match_profile": "Match Profile",
|
"match_profile": "Match Profile",
|
||||||
|
|||||||
@@ -98,6 +98,12 @@ abstract class AppLocalizations {
|
|||||||
Locale('en'),
|
Locale('en'),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// No description provided for @add_team.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Add Team'**
|
||||||
|
String get add_team;
|
||||||
|
|
||||||
/// No description provided for @all_players.
|
/// No description provided for @all_players.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -242,12 +248,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Create new group'**
|
/// **'Create new group'**
|
||||||
String get create_new_group;
|
String get create_new_group;
|
||||||
|
|
||||||
/// No description provided for @created_on.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Created on'**
|
|
||||||
String get created_on;
|
|
||||||
|
|
||||||
/// No description provided for @create_new_match.
|
/// No description provided for @create_new_match.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -260,6 +260,12 @@ abstract class AppLocalizations {
|
|||||||
/// **'Create teams'**
|
/// **'Create teams'**
|
||||||
String get create_teams;
|
String get create_teams;
|
||||||
|
|
||||||
|
/// No description provided for @created_on.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Created on'**
|
||||||
|
String get created_on;
|
||||||
|
|
||||||
/// No description provided for @data.
|
/// No description provided for @data.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -326,18 +332,18 @@ abstract class AppLocalizations {
|
|||||||
/// **'Delete Match'**
|
/// **'Delete Match'**
|
||||||
String get delete_match;
|
String get delete_match;
|
||||||
|
|
||||||
/// No description provided for @drag_to_set_placement.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Drag to set placement'**
|
|
||||||
String get drag_to_set_placement;
|
|
||||||
|
|
||||||
/// No description provided for @description.
|
/// No description provided for @description.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'Description'**
|
/// **'Description'**
|
||||||
String get description;
|
String get description;
|
||||||
|
|
||||||
|
/// No description provided for @drag_to_set_placement.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Drag to set placement'**
|
||||||
|
String get drag_to_set_placement;
|
||||||
|
|
||||||
/// No description provided for @edit_game.
|
/// No description provided for @edit_game.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -356,12 +362,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Edit Match'**
|
/// **'Edit Match'**
|
||||||
String get edit_match;
|
String get edit_match;
|
||||||
|
|
||||||
/// No description provided for @edit_members.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Edit Members'**
|
|
||||||
String get edit_members;
|
|
||||||
|
|
||||||
/// No description provided for @enter_points.
|
/// No description provided for @enter_points.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -464,6 +464,12 @@ abstract class AppLocalizations {
|
|||||||
/// **'Groups'**
|
/// **'Groups'**
|
||||||
String get groups;
|
String get groups;
|
||||||
|
|
||||||
|
/// No description provided for @highest_score.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Highest Score'**
|
||||||
|
String get highest_score;
|
||||||
|
|
||||||
/// No description provided for @home.
|
/// No description provided for @home.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -524,6 +530,24 @@ abstract class AppLocalizations {
|
|||||||
/// **'Live Edit Mode'**
|
/// **'Live Edit Mode'**
|
||||||
String get live_edit_mode;
|
String get live_edit_mode;
|
||||||
|
|
||||||
|
/// No description provided for @loser.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Loser'**
|
||||||
|
String get loser;
|
||||||
|
|
||||||
|
/// No description provided for @lowest_score.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Lowest Score'**
|
||||||
|
String get lowest_score;
|
||||||
|
|
||||||
|
/// No description provided for @manage_members.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Manage Members'**
|
||||||
|
String get manage_members;
|
||||||
|
|
||||||
/// No description provided for @match_in_progress.
|
/// No description provided for @match_in_progress.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -560,6 +584,12 @@ abstract class AppLocalizations {
|
|||||||
/// **'Most Points'**
|
/// **'Most Points'**
|
||||||
String get most_points;
|
String get most_points;
|
||||||
|
|
||||||
|
/// No description provided for @multiple_winners.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Multiple Winners'**
|
||||||
|
String get multiple_winners;
|
||||||
|
|
||||||
/// No description provided for @no_data_available.
|
/// No description provided for @no_data_available.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -578,18 +608,18 @@ abstract class AppLocalizations {
|
|||||||
/// **'No groups created yet'**
|
/// **'No groups created yet'**
|
||||||
String get no_groups_created_yet;
|
String get no_groups_created_yet;
|
||||||
|
|
||||||
/// No description provided for @no_licenses_found.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'No licenses found'**
|
|
||||||
String get no_licenses_found;
|
|
||||||
|
|
||||||
/// No description provided for @no_license_text_available.
|
/// No description provided for @no_license_text_available.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'No license text available'**
|
/// **'No license text available'**
|
||||||
String get no_license_text_available;
|
String get no_license_text_available;
|
||||||
|
|
||||||
|
/// No description provided for @no_licenses_found.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'No licenses found'**
|
||||||
|
String get no_licenses_found;
|
||||||
|
|
||||||
/// No description provided for @no_matches_created_yet.
|
/// No description provided for @no_matches_created_yet.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -656,18 +686,18 @@ abstract class AppLocalizations {
|
|||||||
/// **'Not available'**
|
/// **'Not available'**
|
||||||
String get not_available;
|
String get not_available;
|
||||||
|
|
||||||
/// No description provided for @placement.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Placement'**
|
|
||||||
String get placement;
|
|
||||||
|
|
||||||
/// No description provided for @place.
|
/// No description provided for @place.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'place'**
|
/// **'place'**
|
||||||
String get place;
|
String get place;
|
||||||
|
|
||||||
|
/// No description provided for @placement.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Placement'**
|
||||||
|
String get placement;
|
||||||
|
|
||||||
/// No description provided for @played_matches.
|
/// No description provided for @played_matches.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -782,6 +812,12 @@ abstract class AppLocalizations {
|
|||||||
/// **'Search for players'**
|
/// **'Search for players'**
|
||||||
String get search_for_players;
|
String get search_for_players;
|
||||||
|
|
||||||
|
/// No description provided for @select_loser.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Select Loser'**
|
||||||
|
String get select_loser;
|
||||||
|
|
||||||
/// No description provided for @select_winner.
|
/// No description provided for @select_winner.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -794,12 +830,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Select Winners'**
|
/// **'Select Winners'**
|
||||||
String get select_winners;
|
String get select_winners;
|
||||||
|
|
||||||
/// No description provided for @select_loser.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Select Loser'**
|
|
||||||
String get select_loser;
|
|
||||||
|
|
||||||
/// No description provided for @selected_players.
|
/// No description provided for @selected_players.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
@@ -824,30 +854,6 @@ abstract class AppLocalizations {
|
|||||||
/// **'Single Winner'**
|
/// **'Single Winner'**
|
||||||
String get single_winner;
|
String get single_winner;
|
||||||
|
|
||||||
/// No description provided for @highest_score.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Highest Score'**
|
|
||||||
String get highest_score;
|
|
||||||
|
|
||||||
/// No description provided for @loser.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Loser'**
|
|
||||||
String get loser;
|
|
||||||
|
|
||||||
/// No description provided for @lowest_score.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Lowest Score'**
|
|
||||||
String get lowest_score;
|
|
||||||
|
|
||||||
/// No description provided for @multiple_winners.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Multiple Winners'**
|
|
||||||
String get multiple_winners;
|
|
||||||
|
|
||||||
/// No description provided for @statistics.
|
/// No description provided for @statistics.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import 'app_localizations.dart';
|
|||||||
class AppLocalizationsDe extends AppLocalizations {
|
class AppLocalizationsDe extends AppLocalizations {
|
||||||
AppLocalizationsDe([String locale = 'de']) : super(locale);
|
AppLocalizationsDe([String locale = 'de']) : super(locale);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get add_team => 'Team hinzufügen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get all_players => 'Alle Spieler:innen';
|
String get all_players => 'Alle Spieler:innen';
|
||||||
|
|
||||||
@@ -82,15 +85,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get create_new_group => 'Neue Gruppe erstellen';
|
String get create_new_group => 'Neue Gruppe erstellen';
|
||||||
|
|
||||||
@override
|
|
||||||
String get created_on => 'Erstellt am';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get create_new_match => 'Neues Spiel erstellen';
|
String get create_new_match => 'Neues Spiel erstellen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get create_teams => 'Teams erstellen';
|
String get create_teams => 'Teams erstellen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get created_on => 'Erstellt am';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get data => 'Daten';
|
String get data => 'Daten';
|
||||||
|
|
||||||
@@ -135,10 +138,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get delete_match => 'Spiel löschen';
|
String get delete_match => 'Spiel löschen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get drag_to_set_placement => 'Ziehen um Platzierung zu setzen';
|
String get description => 'Beschreibung';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get description => 'Beschreibung';
|
String get drag_to_set_placement => 'Ziehen um Platzierung zu setzen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get edit_game => 'Spielvorlage bearbeiten';
|
String get edit_game => 'Spielvorlage bearbeiten';
|
||||||
@@ -149,9 +152,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get edit_match => 'Gruppe bearbeiten';
|
String get edit_match => 'Gruppe bearbeiten';
|
||||||
|
|
||||||
@override
|
|
||||||
String get edit_members => 'Mitglieder bearbeiten';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enter_points => 'Punkte eingeben';
|
String get enter_points => 'Punkte eingeben';
|
||||||
|
|
||||||
@@ -207,6 +207,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get groups => 'Gruppen';
|
String get groups => 'Gruppen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get highest_score => 'Höchste Punkte';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get home => 'Startseite';
|
String get home => 'Startseite';
|
||||||
|
|
||||||
@@ -237,6 +240,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get live_edit_mode => 'Live-Bearbeitungsmodus';
|
String get live_edit_mode => 'Live-Bearbeitungsmodus';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loser => 'Verlierer:in';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get lowest_score => 'Niedrigste Punkte';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get manage_members => 'Mitglieder bearbeiten';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get match_in_progress => 'Spiel läuft...';
|
String get match_in_progress => 'Spiel läuft...';
|
||||||
|
|
||||||
@@ -255,6 +267,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get most_points => 'Höchste Punkte';
|
String get most_points => 'Höchste Punkte';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get multiple_winners => 'Mehrere Gewinner:innen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_data_available => 'Keine Daten verfügbar';
|
String get no_data_available => 'Keine Daten verfügbar';
|
||||||
|
|
||||||
@@ -265,10 +280,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get no_groups_created_yet => 'Noch keine Gruppen erstellt';
|
String get no_groups_created_yet => 'Noch keine Gruppen erstellt';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_licenses_found => 'Keine Lizenzen gefunden';
|
String get no_license_text_available => 'Kein Lizenztext verfügbar';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_license_text_available => 'Kein Lizenztext verfügbar';
|
String get no_licenses_found => 'Keine Lizenzen gefunden';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_matches_created_yet => 'Noch keine Spiele erstellt';
|
String get no_matches_created_yet => 'Noch keine Spiele erstellt';
|
||||||
@@ -305,10 +320,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
String get not_available => 'Nicht verfügbar';
|
String get not_available => 'Nicht verfügbar';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get placement => 'Platzierung';
|
String get place => 'Platz';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get place => 'Platz';
|
String get placement => 'Platzierung';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get played_matches => 'Gespielte Spiele';
|
String get played_matches => 'Gespielte Spiele';
|
||||||
@@ -372,15 +387,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get search_for_players => 'Nach Spieler:innen suchen';
|
String get search_for_players => 'Nach Spieler:innen suchen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get select_loser => 'Verlierer:in wählen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get select_winner => 'Gewinner:in wählen';
|
String get select_winner => 'Gewinner:in wählen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get select_winners => 'Gewinner:innen wählen';
|
String get select_winners => 'Gewinner:innen wählen';
|
||||||
|
|
||||||
@override
|
|
||||||
String get select_loser => 'Verlierer:in wählen';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get selected_players => 'Ausgewählte Spieler:innen';
|
String get selected_players => 'Ausgewählte Spieler:innen';
|
||||||
|
|
||||||
@@ -393,18 +408,6 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get single_winner => 'Ein:e Gewinner:in';
|
String get single_winner => 'Ein:e Gewinner:in';
|
||||||
|
|
||||||
@override
|
|
||||||
String get highest_score => 'Höchste Punkte';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get loser => 'Verlierer:in';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get lowest_score => 'Niedrigste Punkte';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get multiple_winners => 'Mehrere Gewinner:innen';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get statistics => 'Statistiken';
|
String get statistics => 'Statistiken';
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import 'app_localizations.dart';
|
|||||||
class AppLocalizationsEn extends AppLocalizations {
|
class AppLocalizationsEn extends AppLocalizations {
|
||||||
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get add_team => 'Add Team';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get all_players => 'All players';
|
String get all_players => 'All players';
|
||||||
|
|
||||||
@@ -82,15 +85,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get create_new_group => 'Create new group';
|
String get create_new_group => 'Create new group';
|
||||||
|
|
||||||
@override
|
|
||||||
String get created_on => 'Created on';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get create_new_match => 'Create new match';
|
String get create_new_match => 'Create new match';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get create_teams => 'Create teams';
|
String get create_teams => 'Create teams';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get created_on => 'Created on';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get data => 'Data';
|
String get data => 'Data';
|
||||||
|
|
||||||
@@ -135,10 +138,10 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get delete_match => 'Delete Match';
|
String get delete_match => 'Delete Match';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get drag_to_set_placement => 'Drag to set placement';
|
String get description => 'Description';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get description => 'Description';
|
String get drag_to_set_placement => 'Drag to set placement';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get edit_game => 'Edit Game';
|
String get edit_game => 'Edit Game';
|
||||||
@@ -149,9 +152,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get edit_match => 'Edit Match';
|
String get edit_match => 'Edit Match';
|
||||||
|
|
||||||
@override
|
|
||||||
String get edit_members => 'Edit Members';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get enter_points => 'Enter points';
|
String get enter_points => 'Enter points';
|
||||||
|
|
||||||
@@ -207,6 +207,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get groups => 'Groups';
|
String get groups => 'Groups';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get highest_score => 'Highest Score';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get home => 'Home';
|
String get home => 'Home';
|
||||||
|
|
||||||
@@ -237,6 +240,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get live_edit_mode => 'Live Edit Mode';
|
String get live_edit_mode => 'Live Edit Mode';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loser => 'Loser';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get lowest_score => 'Lowest Score';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get manage_members => 'Manage Members';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get match_in_progress => 'Match in progress...';
|
String get match_in_progress => 'Match in progress...';
|
||||||
|
|
||||||
@@ -255,6 +267,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get most_points => 'Most Points';
|
String get most_points => 'Most Points';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get multiple_winners => 'Multiple Winners';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_data_available => 'No data available';
|
String get no_data_available => 'No data available';
|
||||||
|
|
||||||
@@ -265,10 +280,10 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get no_groups_created_yet => 'No groups created yet';
|
String get no_groups_created_yet => 'No groups created yet';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_licenses_found => 'No licenses found';
|
String get no_license_text_available => 'No license text available';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_license_text_available => 'No license text available';
|
String get no_licenses_found => 'No licenses found';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get no_matches_created_yet => 'No matches created yet';
|
String get no_matches_created_yet => 'No matches created yet';
|
||||||
@@ -305,10 +320,10 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
String get not_available => 'Not available';
|
String get not_available => 'Not available';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get placement => 'Placement';
|
String get place => 'place';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get place => 'place';
|
String get placement => 'Placement';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get played_matches => 'Played Matches';
|
String get played_matches => 'Played Matches';
|
||||||
@@ -372,15 +387,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get search_for_players => 'Search for players';
|
String get search_for_players => 'Search for players';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get select_loser => 'Select Loser';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get select_winner => 'Select Winner';
|
String get select_winner => 'Select Winner';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get select_winners => 'Select Winners';
|
String get select_winners => 'Select Winners';
|
||||||
|
|
||||||
@override
|
|
||||||
String get select_loser => 'Select Loser';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get selected_players => 'Selected players';
|
String get selected_players => 'Selected players';
|
||||||
|
|
||||||
@@ -393,18 +408,6 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||||||
@override
|
@override
|
||||||
String get single_winner => 'Single Winner';
|
String get single_winner => 'Single Winner';
|
||||||
|
|
||||||
@override
|
|
||||||
String get highest_score => 'Highest Score';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get loser => 'Loser';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get lowest_score => 'Lowest Score';
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get multiple_winners => 'Multiple Winners';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get statistics => 'Statistics';
|
String get statistics => 'Statistics';
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import 'package:tallee/data/models/match.dart';
|
|||||||
import 'package:tallee/data/models/player.dart';
|
import 'package:tallee/data/models/player.dart';
|
||||||
import 'package:tallee/data/models/team.dart';
|
import 'package:tallee/data/models/team.dart';
|
||||||
import 'package:tallee/l10n/generated/app_localizations.dart';
|
import 'package:tallee/l10n/generated/app_localizations.dart';
|
||||||
import 'package:tallee/presentation/views/main_menu/match_view/create_match/create_teams/edit_members_view.dart';
|
import 'package:tallee/presentation/views/main_menu/match_view/create_match/create_teams/manage_members_view.dart';
|
||||||
import 'package:tallee/presentation/views/main_menu/match_view/match_result_view.dart';
|
|
||||||
import 'package:tallee/presentation/widgets/buttons/main_menu_button.dart';
|
import 'package:tallee/presentation/widgets/buttons/main_menu_button.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/team_creation_tile.dart';
|
import 'package:tallee/presentation/widgets/tiles/team_creation_tile.dart';
|
||||||
|
|
||||||
@@ -50,7 +49,6 @@ class _CreateTeamsViewState extends State<CreateTeamsView> {
|
|||||||
|
|
||||||
// Init the controllers
|
// Init the controllers
|
||||||
nameController = teams.map(getNewController).toList();
|
nameController = teams.map(getNewController).toList();
|
||||||
redistributePlayers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -71,36 +69,7 @@ class _CreateTeamsViewState extends State<CreateTeamsView> {
|
|||||||
return TeamCreationTile(
|
return TeamCreationTile(
|
||||||
color: teams[index].color,
|
color: teams[index].color,
|
||||||
controller: nameController[index],
|
controller: nameController[index],
|
||||||
players: teams[index].members,
|
|
||||||
hintText: '${loc.team} ${index + 1}',
|
hintText: '${loc.team} ${index + 1}',
|
||||||
onEdit: () async {
|
|
||||||
final newPlayers = await Navigator.push(
|
|
||||||
context,
|
|
||||||
adaptivePageRoute(
|
|
||||||
fullscreenDialog: true,
|
|
||||||
builder: (context) => EditMembersView(
|
|
||||||
matchPlayer: widget.match.players,
|
|
||||||
teamMember: teams[index].members,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
// Remove the selected players from every team
|
|
||||||
for (final player in newPlayers) {
|
|
||||||
for (final team in teams) {
|
|
||||||
if (team.members.contains(player)) {
|
|
||||||
team.members.remove(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the selected players to the current team
|
|
||||||
teams[index] = teams[index].copyWith(
|
|
||||||
members: newPlayers,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onDelete: teams.length <= 2
|
onDelete: teams.length <= 2
|
||||||
? null
|
? null
|
||||||
: () => _removeTeam(index),
|
: () => _removeTeam(index),
|
||||||
@@ -118,19 +87,10 @@ class _CreateTeamsViewState extends State<CreateTeamsView> {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
// Redistribute
|
|
||||||
MainMenuButton(
|
|
||||||
icon: Icons.cached,
|
|
||||||
text: loc.redistribute,
|
|
||||||
onPressed: () => setState(() {
|
|
||||||
redistributePlayers();
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 15),
|
|
||||||
|
|
||||||
// Add new team
|
// Add new team
|
||||||
MainMenuButton(
|
MainMenuButton(
|
||||||
icon: Icons.add,
|
icon: Icons.add,
|
||||||
|
text: loc.add_team,
|
||||||
onPressed: teams.length >= widget.match.players.length
|
onPressed: teams.length >= widget.match.players.length
|
||||||
? null
|
? null
|
||||||
: addTeam,
|
: addTeam,
|
||||||
@@ -139,21 +99,19 @@ class _CreateTeamsViewState extends State<CreateTeamsView> {
|
|||||||
|
|
||||||
// Confirm teams and start match
|
// Confirm teams and start match
|
||||||
MainMenuButton(
|
MainMenuButton(
|
||||||
icon: Icons.check,
|
icon: Icons.arrow_forward_sharp,
|
||||||
onPressed: teams.every((team) => team.members.isNotEmpty)
|
onPressed: teams.length >= 2
|
||||||
? () async {
|
? () async {
|
||||||
final match = await createMatchWithTeams();
|
final match = await createMatchWithTeams();
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
Navigator.pushAndRemoveUntil(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
adaptivePageRoute(
|
adaptivePageRoute(
|
||||||
fullscreenDialog: true,
|
builder: (context) => ManageMembersView(
|
||||||
builder: (context) => MatchResultView(
|
|
||||||
match: match,
|
match: match,
|
||||||
onWinnerChanged: widget.onWinnerChanged,
|
onWinnerChanged: widget.onWinnerChanged,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(route) => route.isFirst,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,7 +132,6 @@ class _CreateTeamsViewState extends State<CreateTeamsView> {
|
|||||||
final newTeam = getNewTeam();
|
final newTeam = getNewTeam();
|
||||||
teams.add(newTeam);
|
teams.add(newTeam);
|
||||||
nameController.add(getNewController(newTeam));
|
nameController.add(getNewController(newTeam));
|
||||||
redistributePlayers();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,25 +202,6 @@ class _CreateTeamsViewState extends State<CreateTeamsView> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterates through all teams and redistributes players randomly and
|
|
||||||
// as evenly as possible.
|
|
||||||
void redistributePlayers() {
|
|
||||||
for (final team in teams) {
|
|
||||||
team.members.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matchPlayers.isEmpty || teams.isEmpty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final shuffledPlayers = [...matchPlayers]..shuffle(random);
|
|
||||||
|
|
||||||
for (int i = 0; i < shuffledPlayers.length; i++) {
|
|
||||||
final teamIndex = i % teams.length;
|
|
||||||
teams[teamIndex].members.add(shuffledPlayers[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Saves the teams to the database and returns the updated match with the teams.
|
/// Saves the teams to the database and returns the updated match with the teams.
|
||||||
Future<Match> createMatchWithTeams() async {
|
Future<Match> createMatchWithTeams() async {
|
||||||
final db = Provider.of<AppDatabase>(context, listen: false);
|
final db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:tallee/data/models/player.dart';
|
|
||||||
import 'package:tallee/l10n/generated/app_localizations.dart';
|
|
||||||
import 'package:tallee/presentation/widgets/buttons/haptic_icon_button.dart';
|
|
||||||
import 'package:tallee/presentation/widgets/player_selection.dart';
|
|
||||||
|
|
||||||
class EditMembersView extends StatefulWidget {
|
|
||||||
const EditMembersView({
|
|
||||||
super.key,
|
|
||||||
required this.matchPlayer,
|
|
||||||
required this.teamMember,
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<Player> matchPlayer;
|
|
||||||
|
|
||||||
final List<Player> teamMember;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<EditMembersView> createState() => _EditMembersViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EditMembersViewState extends State<EditMembersView> {
|
|
||||||
List<Player> selectedPlayers = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
selectedPlayers = [...widget.teamMember];
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final loc = AppLocalizations.of(context);
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: Text(loc.edit_members),
|
|
||||||
leading: HapticIconButton(
|
|
||||||
onPressed: selectedPlayers.isNotEmpty
|
|
||||||
? () => Navigator.pop(context, selectedPlayers)
|
|
||||||
: null,
|
|
||||||
icon: const Icon(Icons.arrow_back_ios_new_outlined),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: PlayerSelection(
|
|
||||||
initialSelectedPlayers: widget.teamMember,
|
|
||||||
availablePlayers: widget.matchPlayer,
|
|
||||||
onChanged: (List<Player> newSelectedPlayers) {
|
|
||||||
setState(() {
|
|
||||||
selectedPlayers = newSelectedPlayers;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
import 'dart:core' hide Match;
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttericon/rpg_awesome_icons.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:tallee/core/common.dart';
|
||||||
|
import 'package:tallee/core/custom_theme.dart';
|
||||||
|
import 'package:tallee/data/db/database.dart';
|
||||||
|
import 'package:tallee/data/models/match.dart';
|
||||||
|
import 'package:tallee/data/models/team.dart';
|
||||||
|
import 'package:tallee/l10n/generated/app_localizations.dart';
|
||||||
|
import 'package:tallee/presentation/views/main_menu/match_view/match_result_view.dart';
|
||||||
|
import 'package:tallee/presentation/widgets/buttons/main_menu_button.dart';
|
||||||
|
import 'package:tallee/presentation/widgets/tiles/text_icon_list_tile.dart';
|
||||||
|
|
||||||
|
/// Displays the given [teams] as a flat reorderable list where every team is
|
||||||
|
/// preceded by a header row and followed by its members. Members can be
|
||||||
|
/// dragged across team boundaries to be reassigned to another team.
|
||||||
|
class ManageMembersView extends StatefulWidget {
|
||||||
|
const ManageMembersView({
|
||||||
|
super.key,
|
||||||
|
required this.match,
|
||||||
|
required this.onWinnerChanged,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Match match;
|
||||||
|
|
||||||
|
final VoidCallback? onWinnerChanged;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ManageMembersView> createState() => _ManageMembersViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ManageMembersViewState extends State<ManageMembersView> {
|
||||||
|
late AppDatabase db;
|
||||||
|
|
||||||
|
late List<Team> teams;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
db = Provider.of<AppDatabase>(context, listen: false);
|
||||||
|
teams = widget.match.teams!;
|
||||||
|
redistributePlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final loc = AppLocalizations.of(context);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
|
appBar: AppBar(title: Text(loc.manage_members)),
|
||||||
|
body: SafeArea(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ReorderableListView.builder(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
buildDefaultDragHandles: false,
|
||||||
|
itemCount: allItemsCount,
|
||||||
|
onReorder: onReorder,
|
||||||
|
proxyDecorator: (child, index, animation) =>
|
||||||
|
Material(type: MaterialType.transparency, child: child),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final teamIndex = teamIndexForFlat(index);
|
||||||
|
final memberIndex = memberIndexForFlat(index, teamIndex);
|
||||||
|
final team = teams[teamIndex];
|
||||||
|
|
||||||
|
if (memberIndex == -1) {
|
||||||
|
return buildTeamTile(team: team);
|
||||||
|
}
|
||||||
|
|
||||||
|
final player = team.members[memberIndex];
|
||||||
|
return ReorderableDelayedDragStartListener(
|
||||||
|
key: ValueKey('player_${player.id}'),
|
||||||
|
index: index,
|
||||||
|
child: TextIconListTile(
|
||||||
|
text: player.name,
|
||||||
|
suffixText: getNameCountText(player),
|
||||||
|
icon: Icons.drag_handle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: MediaQuery.of(context).padding.bottom,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Center(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
MainMenuButton(
|
||||||
|
onPressed: () => setState(() {
|
||||||
|
redistributePlayers();
|
||||||
|
}),
|
||||||
|
icon: Icons.cached,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 16),
|
||||||
|
MainMenuButton(
|
||||||
|
onPressed: allTeamsHaveMembers
|
||||||
|
? () async => submitMatch()
|
||||||
|
: null,
|
||||||
|
text: loc.create_match,
|
||||||
|
icon: RpgAwesome.clovers_card,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void submitMatch() async {
|
||||||
|
await db.matchDao.addMatch(match: widget.match);
|
||||||
|
if (mounted) {
|
||||||
|
Navigator.pushAndRemoveUntil(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => MatchResultView(
|
||||||
|
match: widget.match,
|
||||||
|
onWinnerChanged: widget.onWinnerChanged,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(route) => route.isFirst,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get allTeamsHaveMembers {
|
||||||
|
return teams.every((team) => team.members.isNotEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterates through all teams and redistributes players randomly and
|
||||||
|
// as evenly as possible.
|
||||||
|
void redistributePlayers() {
|
||||||
|
for (final team in teams) {
|
||||||
|
team.members.clear();
|
||||||
|
}
|
||||||
|
var matchPlayers = widget.match.players;
|
||||||
|
Random random = Random();
|
||||||
|
|
||||||
|
if (matchPlayers.isEmpty || teams.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final shuffledPlayers = [...matchPlayers]..shuffle(random);
|
||||||
|
|
||||||
|
for (int i = 0; i < shuffledPlayers.length; i++) {
|
||||||
|
final teamIndex = i % teams.length;
|
||||||
|
teams[teamIndex].members.add(shuffledPlayers[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Total players + teams length
|
||||||
|
int get allItemsCount {
|
||||||
|
var count = 0;
|
||||||
|
for (final team in teams) {
|
||||||
|
count += 1 + team.members.length;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the index of the team that owns the flat-list item at [flatIndex].
|
||||||
|
int teamIndexForFlat(int flatIndex) {
|
||||||
|
var remaining = flatIndex;
|
||||||
|
for (var i = 0; i < teams.length; i++) {
|
||||||
|
final size = 1 + teams[i].members.length;
|
||||||
|
if (remaining < size) return i;
|
||||||
|
remaining -= size;
|
||||||
|
}
|
||||||
|
return teams.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the member index within its team, or `-1` if the item at
|
||||||
|
/// [flatIndex] is the team header.
|
||||||
|
int memberIndexForFlat(int flatIndex, int teamIndex) {
|
||||||
|
var offset = 0;
|
||||||
|
for (var i = 0; i < teamIndex; i++) {
|
||||||
|
offset += 1 + teams[i].members.length;
|
||||||
|
}
|
||||||
|
// offset now points to the header of [teamIndex]. Anything beyond is a
|
||||||
|
// member of that team.
|
||||||
|
final localIndex = flatIndex - offset;
|
||||||
|
return localIndex == 0 ? -1 : localIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onReorder(int oldIndex, int newIndex) {
|
||||||
|
final sourceTeamIndex = teamIndexForFlat(oldIndex);
|
||||||
|
final sourceMemberIndex = memberIndexForFlat(oldIndex, sourceTeamIndex);
|
||||||
|
|
||||||
|
// Headers themselves can't be reordered.
|
||||||
|
if (sourceMemberIndex == -1) return;
|
||||||
|
|
||||||
|
// Flutter convention: when moving down, the target index is shifted by 1
|
||||||
|
// because the item is removed first.
|
||||||
|
var targetIndex = newIndex;
|
||||||
|
if (newIndex > oldIndex) targetIndex -= 1;
|
||||||
|
targetIndex = targetIndex.clamp(0, allItemsCount - 1);
|
||||||
|
|
||||||
|
// Resolve target location based on the item currently at [targetIndex]
|
||||||
|
// *before* the move.
|
||||||
|
int destTeamIndex;
|
||||||
|
int insertPositionInTeam;
|
||||||
|
|
||||||
|
if (targetIndex >= allItemsCount - 1 && newIndex >= allItemsCount) {
|
||||||
|
// Dropped at the very end -> append to the last team.
|
||||||
|
destTeamIndex = teams.length - 1;
|
||||||
|
insertPositionInTeam = teams[destTeamIndex].members.length;
|
||||||
|
} else {
|
||||||
|
destTeamIndex = teamIndexForFlat(targetIndex);
|
||||||
|
final anchorMemberIndex = memberIndexForFlat(targetIndex, destTeamIndex);
|
||||||
|
|
||||||
|
if (anchorMemberIndex == -1) {
|
||||||
|
// Dropped right before a header -> append to the previous team.
|
||||||
|
destTeamIndex = destTeamIndex - 1;
|
||||||
|
if (destTeamIndex < 0) {
|
||||||
|
// Dropped above the very first header -> stay in team 0 at top.
|
||||||
|
destTeamIndex = 0;
|
||||||
|
insertPositionInTeam = 0;
|
||||||
|
} else {
|
||||||
|
insertPositionInTeam = teams[destTeamIndex].members.length;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
insertPositionInTeam = anchorMemberIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
final sourceMembers = teams[sourceTeamIndex].members;
|
||||||
|
final player = sourceMembers.removeAt(sourceMemberIndex);
|
||||||
|
|
||||||
|
// Adjust insert index if we removed from before the insert point in the
|
||||||
|
// same team.
|
||||||
|
if (sourceTeamIndex == destTeamIndex &&
|
||||||
|
insertPositionInTeam > sourceMembers.length) {
|
||||||
|
insertPositionInTeam = sourceMembers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
teams[destTeamIndex].members.insert(insertPositionInTeam, player);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget buildTeamTile({required Team team}) {
|
||||||
|
final color = getColorFromGameColor(team.color);
|
||||||
|
return Padding(
|
||||||
|
key: ValueKey('header_${team.id}'),
|
||||||
|
padding: const EdgeInsets.fromLTRB(12, 16, 12, 8),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 14,
|
||||||
|
height: 14,
|
||||||
|
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
team.name,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: CustomTheme.textColor,
|
||||||
|
fontSize: 17,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${team.members.length}',
|
||||||
|
style: const TextStyle(
|
||||||
|
color: CustomTheme.hintColor,
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,34 +3,26 @@ import 'package:tallee/core/common.dart';
|
|||||||
import 'package:tallee/core/constants.dart';
|
import 'package:tallee/core/constants.dart';
|
||||||
import 'package:tallee/core/custom_theme.dart';
|
import 'package:tallee/core/custom_theme.dart';
|
||||||
import 'package:tallee/core/enums.dart';
|
import 'package:tallee/core/enums.dart';
|
||||||
import 'package:tallee/data/models/player.dart';
|
|
||||||
import 'package:tallee/l10n/generated/app_localizations.dart';
|
import 'package:tallee/l10n/generated/app_localizations.dart';
|
||||||
import 'package:tallee/presentation/widgets/buttons/animated_dialog_button.dart';
|
import 'package:tallee/presentation/widgets/buttons/animated_dialog_button.dart';
|
||||||
import 'package:tallee/presentation/widgets/text_input/text_input_field.dart';
|
import 'package:tallee/presentation/widgets/text_input/text_input_field.dart';
|
||||||
import 'package:tallee/presentation/widgets/tiles/text_icon_tile.dart';
|
|
||||||
|
|
||||||
class TeamCreationTile extends StatefulWidget {
|
class TeamCreationTile extends StatefulWidget {
|
||||||
const TeamCreationTile({
|
const TeamCreationTile({
|
||||||
super.key,
|
super.key,
|
||||||
required this.color,
|
required this.color,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
required this.players,
|
|
||||||
required this.hintText,
|
required this.hintText,
|
||||||
this.onEdit,
|
|
||||||
this.onDelete,
|
this.onDelete,
|
||||||
this.onColorSelection,
|
this.onColorSelection,
|
||||||
});
|
});
|
||||||
|
|
||||||
final GameColor color;
|
final GameColor color;
|
||||||
|
|
||||||
final List<Player> players;
|
|
||||||
|
|
||||||
final TextEditingController controller;
|
final TextEditingController controller;
|
||||||
|
|
||||||
final String hintText;
|
final String hintText;
|
||||||
|
|
||||||
final VoidCallback? onEdit;
|
|
||||||
|
|
||||||
final VoidCallback? onDelete;
|
final VoidCallback? onDelete;
|
||||||
|
|
||||||
final ValueChanged<GameColor>? onColorSelection;
|
final ValueChanged<GameColor>? onColorSelection;
|
||||||
@@ -112,45 +104,6 @@ class _TeamCreationTileState extends State<TeamCreationTile> {
|
|||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Text(
|
|
||||||
loc.players,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: CustomTheme.textColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
|
||||||
if (widget.players.isEmpty)
|
|
||||||
Text(
|
|
||||||
loc.no_players_selected,
|
|
||||||
style: const TextStyle(color: CustomTheme.hintColor),
|
|
||||||
)
|
|
||||||
else
|
|
||||||
Wrap(
|
|
||||||
spacing: 8,
|
|
||||||
runSpacing: 8,
|
|
||||||
children: widget.players
|
|
||||||
.map(
|
|
||||||
(player) => TextIconTile(
|
|
||||||
text: player.name,
|
|
||||||
suffixText: getNameCountText(player),
|
|
||||||
iconEnabled: false,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList(),
|
|
||||||
),
|
|
||||||
if (widget.onEdit != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 12),
|
|
||||||
child: AnimatedDialogButton(
|
|
||||||
buttonConstraints: const BoxConstraints(
|
|
||||||
minWidth: double.infinity,
|
|
||||||
),
|
|
||||||
buttonText: loc.edit_members,
|
|
||||||
onPressed: widget.onEdit!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user