Implemented reordering
This commit is contained in:
@@ -5,6 +5,7 @@ import 'package:cabo_counter/services/local_storage_service.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
|
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
|
||||||
class RoundView extends StatefulWidget {
|
class RoundView extends StatefulWidget {
|
||||||
final GameSession gameSession;
|
final GameSession gameSession;
|
||||||
@@ -67,6 +68,8 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
|
final bottomInset = MediaQuery.of(context).viewInsets.bottom;
|
||||||
|
final rotatedPlayers = _getRotatedPlayers();
|
||||||
|
final originalIndices = _getOriginalIndices();
|
||||||
|
|
||||||
return CupertinoPageScaffold(
|
return CupertinoPageScaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
@@ -175,9 +178,10 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
ListView.builder(
|
ListView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
itemCount: widget.gameSession.players.length,
|
itemCount: rotatedPlayers.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final name = widget.gameSession.players[index];
|
final originalIndex = originalIndices[index];
|
||||||
|
final name = rotatedPlayers[index];
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 10, horizontal: 20),
|
vertical: 10, horizontal: 20),
|
||||||
@@ -187,13 +191,23 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
backgroundColor: CupertinoColors.secondaryLabel,
|
backgroundColor: CupertinoColors.secondaryLabel,
|
||||||
title: Row(children: [
|
title: Row(children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Row(children: [
|
||||||
name,
|
Text(
|
||||||
overflow: TextOverflow.ellipsis,
|
name,
|
||||||
))
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: index == 0,
|
||||||
|
child: const SizedBox(width: 10),
|
||||||
|
),
|
||||||
|
Visibility(
|
||||||
|
visible: index == 0,
|
||||||
|
child: const Icon(FontAwesomeIcons.medal,
|
||||||
|
size: 15))
|
||||||
|
]))
|
||||||
]),
|
]),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'${widget.gameSession.playerScores[index]}'
|
'${widget.gameSession.playerScores[originalIndex]}'
|
||||||
' ${AppLocalizations.of(context).points}'),
|
' ${AppLocalizations.of(context).points}'),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -201,7 +215,7 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
width: 100,
|
width: 100,
|
||||||
child: CupertinoTextField(
|
child: CupertinoTextField(
|
||||||
maxLength: 3,
|
maxLength: 3,
|
||||||
focusNode: _focusNodeList[index],
|
focusNode: _focusNodeList[originalIndex],
|
||||||
keyboardType:
|
keyboardType:
|
||||||
const TextInputType.numberWithOptions(
|
const TextInputType.numberWithOptions(
|
||||||
signed: true,
|
signed: true,
|
||||||
@@ -216,12 +230,13 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
1
|
1
|
||||||
? TextInputAction.done
|
? TextInputAction.done
|
||||||
: TextInputAction.next,
|
: TextInputAction.next,
|
||||||
controller: _scoreControllerList[index],
|
controller:
|
||||||
|
_scoreControllerList[originalIndex],
|
||||||
placeholder:
|
placeholder:
|
||||||
AppLocalizations.of(context).points,
|
AppLocalizations.of(context).points,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
onSubmitted: (_) =>
|
onSubmitted: (_) =>
|
||||||
_focusNextTextfield(index),
|
_focusNextTextfield(originalIndex),
|
||||||
onChanged: (_) => setState(() {}),
|
onChanged: (_) => setState(() {}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -230,7 +245,8 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_kamikazePlayerIndex =
|
_kamikazePlayerIndex =
|
||||||
(_kamikazePlayerIndex == index)
|
(_kamikazePlayerIndex ==
|
||||||
|
originalIndex)
|
||||||
? null
|
? null
|
||||||
: index;
|
: index;
|
||||||
});
|
});
|
||||||
@@ -240,17 +256,20 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
height: 24,
|
height: 24,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
color: _kamikazePlayerIndex == index
|
color: _kamikazePlayerIndex ==
|
||||||
|
originalIndex
|
||||||
? CupertinoColors.systemRed
|
? CupertinoColors.systemRed
|
||||||
: CupertinoColors
|
: CupertinoColors
|
||||||
.tertiarySystemFill,
|
.tertiarySystemFill,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: _kamikazePlayerIndex == index
|
color: _kamikazePlayerIndex ==
|
||||||
|
originalIndex
|
||||||
? CupertinoColors.systemRed
|
? CupertinoColors.systemRed
|
||||||
: CupertinoColors.systemGrey,
|
: CupertinoColors.systemGrey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: _kamikazePlayerIndex == index
|
child: _kamikazePlayerIndex ==
|
||||||
|
originalIndex
|
||||||
? const Icon(
|
? const Icon(
|
||||||
CupertinoIcons.exclamationmark,
|
CupertinoIcons.exclamationmark,
|
||||||
size: 16,
|
size: 16,
|
||||||
@@ -338,8 +357,12 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
/// Focuses the next text field in the list of text fields.
|
/// Focuses the next text field in the list of text fields.
|
||||||
/// [index] is the index of the current text field.
|
/// [index] is the index of the current text field.
|
||||||
void _focusNextTextfield(int index) {
|
void _focusNextTextfield(int index) {
|
||||||
if (index < widget.gameSession.players.length - 1) {
|
final originalIndices = _getOriginalIndices();
|
||||||
FocusScope.of(context).requestFocus(_focusNodeList[index + 1]);
|
final currentPos = originalIndices.indexOf(index);
|
||||||
|
|
||||||
|
if (currentPos < originalIndices.length - 1) {
|
||||||
|
FocusScope.of(context)
|
||||||
|
.requestFocus(_focusNodeList[originalIndices[currentPos + 1]]);
|
||||||
} else {
|
} else {
|
||||||
_focusNodeList[index].unfocus();
|
_focusNodeList[index].unfocus();
|
||||||
}
|
}
|
||||||
@@ -451,6 +474,47 @@ class _RoundViewState extends State<RoundView> {
|
|||||||
return resultText;
|
return resultText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _getRotatedPlayers() {
|
||||||
|
final winnerIndex = _getPreviousRoundWinnerIndex();
|
||||||
|
return [
|
||||||
|
widget.gameSession.players[winnerIndex],
|
||||||
|
...widget.gameSession.players.sublist(winnerIndex + 1),
|
||||||
|
...widget.gameSession.players.sublist(0, winnerIndex)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> _getOriginalIndices() {
|
||||||
|
final winnerIndex = _getPreviousRoundWinnerIndex();
|
||||||
|
return [
|
||||||
|
winnerIndex,
|
||||||
|
...List.generate(widget.gameSession.players.length - winnerIndex - 1,
|
||||||
|
(i) => winnerIndex + i + 1),
|
||||||
|
...List.generate(winnerIndex, (i) => i)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
int _getPreviousRoundWinnerIndex() {
|
||||||
|
if (widget.roundNumber == 1) {
|
||||||
|
return 0; // In der ersten Runde einfach den ersten Spieler nehmen
|
||||||
|
}
|
||||||
|
|
||||||
|
final previousRound = widget.gameSession.roundList[widget.roundNumber - 2];
|
||||||
|
final scores = previousRound.scores;
|
||||||
|
|
||||||
|
// Finde den niedrigsten Score (Gewinner)
|
||||||
|
int minScore = scores[0];
|
||||||
|
int winnerIndex = 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < scores.length; i++) {
|
||||||
|
if (scores[i] < minScore) {
|
||||||
|
minScore = scores[i];
|
||||||
|
winnerIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return winnerIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
for (final controller in _scoreControllerList) {
|
for (final controller in _scoreControllerList) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: cabo_counter
|
|||||||
description: "Mobile app for the card game Cabo"
|
description: "Mobile app for the card game Cabo"
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 0.4.6+504
|
version: 0.4.6+505
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.5.4
|
sdk: ^3.5.4
|
||||||
|
|||||||
Reference in New Issue
Block a user