This commit is contained in:
2026-05-04 15:00:09 +01:00
parent 648fae99b1
commit c3a90f2816
2 changed files with 51 additions and 12 deletions

View File

@@ -377,6 +377,42 @@ class PlacarController extends ChangeNotifier {
notifyListeners();
}
// ── TROCAR JOGADORES NO CAMPO ──────────────────────────────────────────────
void swapCourtPlayers(String draggedPlayerData, String targetPlayerData) {
// Verifica se são da mesma equipa (Minha Equipa)
if (draggedPlayerData.startsWith("player_my_") && targetPlayerData.startsWith("player_my_")) {
String id1 = draggedPlayerData.replaceAll("player_my_", "");
String id2 = targetPlayerData.replaceAll("player_my_", "");
int idx1 = myCourt.indexOf(id1);
int idx2 = myCourt.indexOf(id2);
if (idx1 != -1 && idx2 != -1) {
myCourt[idx1] = id2;
myCourt[idx2] = id1;
}
}
// Verifica se são da mesma equipa (Adversário)
else if (draggedPlayerData.startsWith("player_opp_") && targetPlayerData.startsWith("player_opp_")) {
String id1 = draggedPlayerData.replaceAll("player_opp_", "");
String id2 = targetPlayerData.replaceAll("player_opp_", "");
int idx1 = oppCourt.indexOf(id1);
int idx2 = oppCourt.indexOf(id2);
if (idx1 != -1 && idx2 != -1) {
oppCourt[idx1] = id2;
oppCourt[idx2] = id1;
}
} else {
// Se forem de equipas diferentes ou dados inválidos, ignora.
return;
}
_scheduleAutoSave();
notifyListeners();
}
void registerShotFromPopup(BuildContext context, String action, String targetPlayer, String zone, int points, double relativeX, double relativeY) {
String playerId = targetPlayer.replaceAll("player_my_", "").replaceAll("player_opp_", "");
bool isMake = action.startsWith("add_");
@@ -672,6 +708,7 @@ class PlacarController extends ChangeNotifier {
_autoSaveTimer?.cancel();
super.dispose();
}
Future<void> saveGameStats(BuildContext context) async {
final supabase = Supabase.instance.client;
isSaving = true;
@@ -784,7 +821,7 @@ Future<void> saveGameStats(BuildContext context) async {
}
});
// 3. Preparar os Locais dos Lançamentos (MAPA DE CALOR) - O QUE FALTAVA
// 3. Preparar os Locais dos Lançamentos (MAPA DE CALOR)
List<Map<String, dynamic>> batchShots = [];
for (var shot in matchShots) {
if (!shot.playerId.startsWith("fake_")) {

View File

@@ -2,9 +2,6 @@ import 'package:flutter/material.dart';
import 'package:playmaker/classe/theme.dart';
import 'package:playmaker/controllers/placar_controller.dart';
// ============================================================================
// 4. PAINEL DE BOTÕES DE ACÇÃO (DRAG & DROP)
// ============================================================================
class ActionButtonsPanel extends StatelessWidget {
final PlacarController controller;
final double sf;
@@ -24,23 +21,29 @@ class ActionButtonsPanel extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
_columnBtn([
_dragAndTargetBtn("-1", AppTheme.actionMiss, "miss_1", baseSize, feedSize, sf, badge: ""),
// 🔴 1ª Linha: Agora "sub_pts_1" (Anular pontos)
_dragAndTargetBtn("-1", AppTheme.actionMiss, "sub_pts_1", baseSize, feedSize, sf, badge: ""),
_dragAndTargetBtn("1", AppTheme.actionPoints, "add_pts_1", baseSize, feedSize, sf, badge: "FTM"),
_dragAndTargetBtn("1", AppTheme.actionPoints, "sub_pts_1", baseSize, feedSize, sf, badge: "FTA", isX: true),
// ❌ 3ª Linha: Agora "miss_1" (Falhados)
_dragAndTargetBtn("1", AppTheme.actionPoints, "miss_1", baseSize, feedSize, sf, badge: "FTA", isX: true),
_dragAndTargetBtn("STL", AppTheme.actionSteal, "add_stl", baseSize, feedSize, sf, badge: "STL"),
], gap),
SizedBox(width: gap),
_columnBtn([
_dragAndTargetBtn("-2", AppTheme.actionMiss, "miss_2", baseSize, feedSize, sf, badge: ""),
// 🔴 1ª Linha: Agora "sub_pts_2" (Anular pontos)
_dragAndTargetBtn("-2", AppTheme.actionMiss, "sub_pts_2", baseSize, feedSize, sf, badge: ""),
_dragAndTargetBtn("2", AppTheme.actionPoints, "add_pts_2", baseSize, feedSize, sf, badge: "2PM"),
_dragAndTargetBtn("2", AppTheme.actionPoints, "sub_pts_2", baseSize, feedSize, sf, badge: "2PA", isX: true),
// ❌ 3ª Linha: Agora "miss_2" (Falhados)
_dragAndTargetBtn("2", AppTheme.actionPoints, "miss_2", baseSize, feedSize, sf, badge: "2PA", isX: true),
_dragAndTargetBtn("AST", AppTheme.actionAssist, "add_ast", baseSize, feedSize, sf, badge: "AST"),
], gap),
SizedBox(width: gap),
_columnBtn([
_dragAndTargetBtn("-3", AppTheme.actionMiss, "miss_3", baseSize, feedSize, sf, badge: ""),
// 🔴 1ª Linha: Agora "sub_pts_3" (Anular pontos)
_dragAndTargetBtn("-3", AppTheme.actionMiss, "sub_pts_3", baseSize, feedSize, sf, badge: ""),
_dragAndTargetBtn("3", AppTheme.actionPoints, "add_pts_3", baseSize, feedSize, sf, badge: "3PM"),
_dragAndTargetBtn("3", AppTheme.actionPoints, "sub_pts_3", baseSize, feedSize, sf, badge: "3PA", isX: true),
// ❌ 3ª Linha: Agora "miss_3" (Falhados)
_dragAndTargetBtn("3", AppTheme.actionPoints, "miss_3", baseSize, feedSize, sf, badge: "3PA", isX: true),
_dragAndTargetBtn("TOV", AppTheme.actionMiss, "add_tov", baseSize, feedSize, sf, badge: "TOV"),
], gap),
SizedBox(width: gap),
@@ -53,7 +56,6 @@ class ActionButtonsPanel extends StatelessWidget {
),
);
}
Widget _columnBtn(List<Widget> children, double gap) {
return Column(
mainAxisSize: MainAxisSize.min,