Added ui implementation

This commit is contained in:
2026-04-19 22:49:21 +02:00
parent a1398623b0
commit 9a2afbfd3b
8 changed files with 73 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:tallee/core/enums.dart'; import 'package:tallee/core/enums.dart';
import 'package:tallee/data/models/match.dart'; import 'package:tallee/data/models/match.dart';
import 'package:tallee/data/models/player.dart';
import 'package:tallee/l10n/generated/app_localizations.dart'; import 'package:tallee/l10n/generated/app_localizations.dart';
/// Translates a [Ruleset] enum value to its corresponding localized string. /// Translates a [Ruleset] enum value to its corresponding localized string.
@@ -43,3 +44,10 @@ String getExtraPlayerCount(Match match) {
} }
return ' + ${count.toString()}'; return ' + ${count.toString()}';
} }
String getNameCountText(Player player) {
if (player.nameCount >= 1) {
return ' #${player.nameCount}';
}
return '';
}

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:tallee/core/adaptive_page_route.dart'; import 'package:tallee/core/adaptive_page_route.dart';
import 'package:tallee/core/common.dart';
import 'package:tallee/core/custom_theme.dart'; import 'package:tallee/core/custom_theme.dart';
import 'package:tallee/data/db/database.dart'; import 'package:tallee/data/db/database.dart';
import 'package:tallee/data/models/group.dart'; import 'package:tallee/data/models/group.dart';
@@ -153,6 +154,7 @@ class _GroupDetailViewState extends State<GroupDetailView> {
children: _group.members.map((member) { children: _group.members.map((member) {
return TextIconTile( return TextIconTile(
text: member.name, text: member.name,
suffixText: getNameCountText(member),
iconEnabled: false, iconEnabled: false,
); );
}).toList(), }).toList(),

View File

@@ -161,6 +161,7 @@ class _MatchDetailViewState extends State<MatchDetailView> {
children: match.players.map((player) { children: match.players.map((player) {
return TextIconTile( return TextIconTile(
text: player.name, text: player.name,
suffixText: getNameCountText(player),
iconEnabled: false, iconEnabled: false,
); );
}).toList(), }).toList(),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
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/data/db/database.dart'; import 'package:tallee/data/db/database.dart';
@@ -140,6 +141,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
padding: const EdgeInsets.only(right: 8.0), padding: const EdgeInsets.only(right: 8.0),
child: TextIconTile( child: TextIconTile(
text: player.name, text: player.name,
suffixText: getNameCountText(player),
onIconTap: () { onIconTap: () {
setState(() { setState(() {
// Removes the player from the selection and notifies the parent. // Removes the player from the selection and notifies the parent.
@@ -193,6 +195,7 @@ class _PlayerSelectionState extends State<PlayerSelection> {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
return TextIconListTile( return TextIconListTile(
text: suggestedPlayers[index].name, text: suggestedPlayers[index].name,
suffixText: getNameCountText(suggestedPlayers[index]),
onPressed: () { onPressed: () {
setState(() { setState(() {
// If the player is not already selected // If the player is not already selected

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:tallee/core/common.dart';
import 'package:tallee/core/custom_theme.dart'; import 'package:tallee/core/custom_theme.dart';
import 'package:tallee/data/models/group.dart'; import 'package:tallee/data/models/group.dart';
import 'package:tallee/presentation/widgets/tiles/text_icon_tile.dart'; import 'package:tallee/presentation/widgets/tiles/text_icon_tile.dart';
@@ -81,7 +82,11 @@ class _GroupTileState extends State<GroupTile> {
for (var member in [ for (var member in [
...widget.group.members, ...widget.group.members,
]..sort((a, b) => a.name.compareTo(b.name))) ]..sort((a, b) => a.name.compareTo(b.name)))
TextIconTile(text: member.name, iconEnabled: false), TextIconTile(
text: member.name,
suffixText: getNameCountText(member),
iconEnabled: false,
),
], ],
), ),
const SizedBox(height: 2.5), const SizedBox(height: 2.5),

View File

@@ -203,7 +203,11 @@ class _MatchTileState extends State<MatchTile> {
spacing: 6, spacing: 6,
runSpacing: 6, runSpacing: 6,
children: players.map((player) { children: players.map((player) {
return TextIconTile(text: player.name, iconEnabled: false); return TextIconTile(
text: player.name,
suffixText: getNameCountText(player),
iconEnabled: false,
);
}).toList(), }).toList(),
), ),
], ],

View File

@@ -9,6 +9,7 @@ class TextIconListTile extends StatelessWidget {
const TextIconListTile({ const TextIconListTile({
super.key, super.key,
required this.text, required this.text,
this.suffixText = '',
this.iconEnabled = true, this.iconEnabled = true,
this.onPressed, this.onPressed,
}); });
@@ -16,6 +17,9 @@ class TextIconListTile extends StatelessWidget {
/// The text to display in the tile. /// The text to display in the tile.
final String text; final String text;
/// An optional suffix text to display after the main text.
final String suffixText;
/// A boolean to determine if the icon should be displayed. /// A boolean to determine if the icon should be displayed.
final bool iconEnabled; final bool iconEnabled;
@@ -35,14 +39,29 @@ class TextIconListTile extends StatelessWidget {
Flexible( Flexible(
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 12.5), padding: const EdgeInsets.symmetric(vertical: 12.5),
child: Text( child: RichText(
text,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
text: TextSpan(
style: DefaultTextStyle.of(context).style,
children: [
TextSpan(
text: text,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
), ),
TextSpan(
text: suffixText,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: CustomTheme.textColor.withAlpha(100),
),
),
],
),
),
), ),
), ),
if (iconEnabled) if (iconEnabled)

View File

@@ -9,6 +9,7 @@ class TextIconTile extends StatelessWidget {
const TextIconTile({ const TextIconTile({
super.key, super.key,
required this.text, required this.text,
this.suffixText = '',
this.iconEnabled = true, this.iconEnabled = true,
this.onIconTap, this.onIconTap,
}); });
@@ -16,6 +17,8 @@ class TextIconTile extends StatelessWidget {
/// The text to display in the tile. /// The text to display in the tile.
final String text; final String text;
final String suffixText;
/// A boolean to determine if the icon should be displayed. /// A boolean to determine if the icon should be displayed.
final bool iconEnabled; final bool iconEnabled;
@@ -36,10 +39,28 @@ class TextIconTile extends StatelessWidget {
children: [ children: [
if (iconEnabled) const SizedBox(width: 3), if (iconEnabled) const SizedBox(width: 3),
Flexible( Flexible(
child: Text( child: RichText(
text,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), text: TextSpan(
style: DefaultTextStyle.of(context).style,
children: [
TextSpan(
text: text,
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
TextSpan(
text: suffixText,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
color: CustomTheme.textColor.withAlpha(120),
),
),
],
),
), ),
), ),
if (iconEnabled) ...<Widget>[ if (iconEnabled) ...<Widget>[