fazer pdf
This commit is contained in:
@@ -78,7 +78,6 @@ class PlacarController extends ChangeNotifier {
|
|||||||
String? pendingPlayerId;
|
String? pendingPlayerId;
|
||||||
List<ShotRecord> matchShots = [];
|
List<ShotRecord> matchShots = [];
|
||||||
|
|
||||||
// Lista para o Histórico de Jogadas
|
|
||||||
List<String> playByPlay = [];
|
List<String> playByPlay = [];
|
||||||
|
|
||||||
ValueNotifier<Duration> durationNotifier = ValueNotifier(const Duration(minutes: 10));
|
ValueNotifier<Duration> durationNotifier = ValueNotifier(const Duration(minutes: 10));
|
||||||
@@ -113,7 +112,6 @@ class PlacarController extends ChangeNotifier {
|
|||||||
|
|
||||||
gameWasAlreadyFinished = gameResponse['status'] == 'Terminado';
|
gameWasAlreadyFinished = gameResponse['status'] == 'Terminado';
|
||||||
|
|
||||||
// CARREGAR HISTÓRICO DA BASE DE DADOS
|
|
||||||
if (gameResponse['play_by_play'] != null) {
|
if (gameResponse['play_by_play'] != null) {
|
||||||
playByPlay = List<String>.from(gameResponse['play_by_play']);
|
playByPlay = List<String>.from(gameResponse['play_by_play']);
|
||||||
} else {
|
} else {
|
||||||
@@ -147,6 +145,7 @@ class PlacarController extends ChangeNotifier {
|
|||||||
"stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
|
"stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
|
||||||
"fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
|
"fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
|
||||||
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
|
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
|
||||||
|
"p2m": s['p2m'] ?? 0, "p2a": s['p2a'] ?? 0, "p3m": s['p3m'] ?? 0, "p3a": s['p3a'] ?? 0,
|
||||||
};
|
};
|
||||||
myFouls += (s['fls'] as int? ?? 0);
|
myFouls += (s['fls'] as int? ?? 0);
|
||||||
}
|
}
|
||||||
@@ -166,6 +165,7 @@ class PlacarController extends ChangeNotifier {
|
|||||||
"stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
|
"stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
|
||||||
"fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
|
"fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
|
||||||
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
|
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
|
||||||
|
"p2m": s['p2m'] ?? 0, "p2a": s['p2a'] ?? 0, "p3m": s['p3m'] ?? 0, "p3a": s['p3a'] ?? 0,
|
||||||
};
|
};
|
||||||
opponentFouls += (s['fls'] as int? ?? 0);
|
opponentFouls += (s['fls'] as int? ?? 0);
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,8 @@ class PlacarController extends ChangeNotifier {
|
|||||||
|
|
||||||
playerStats[id] = {
|
playerStats[id] = {
|
||||||
"pts": 0, "rbs": 0, "ast": 0, "stl": 0, "tov": 0, "blk": 0,
|
"pts": 0, "rbs": 0, "ast": 0, "stl": 0, "tov": 0, "blk": 0,
|
||||||
"fls": 0, "fgm": 0, "fga": 0, "ftm": 0, "fta": 0, "orb": 0, "drb": 0
|
"fls": 0, "fgm": 0, "fga": 0, "ftm": 0, "fta": 0, "orb": 0, "drb": 0,
|
||||||
|
"p2m": 0, "p2a": 0, "p3m": 0, "p3a": 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isMyTeam) {
|
if (isMyTeam) {
|
||||||
@@ -231,7 +232,7 @@ class PlacarController extends ChangeNotifier {
|
|||||||
'playerStats': playerStats,
|
'playerStats': playerStats,
|
||||||
'myCourt': myCourt, 'myBench': myBench, 'oppCourt': oppCourt, 'oppBench': oppBench,
|
'myCourt': myCourt, 'myBench': myBench, 'oppCourt': oppCourt, 'oppBench': oppBench,
|
||||||
'matchShots': matchShots.map((s) => s.toJson()).toList(),
|
'matchShots': matchShots.map((s) => s.toJson()).toList(),
|
||||||
'playByPlay': playByPlay, // Guarda o histórico no telemóvel
|
'playByPlay': playByPlay,
|
||||||
};
|
};
|
||||||
await prefs.setString('backup_$gameId', jsonEncode(backupData));
|
await prefs.setString('backup_$gameId', jsonEncode(backupData));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -357,13 +358,8 @@ class PlacarController extends ChangeNotifier {
|
|||||||
String name = playerNames[playerId] ?? "Jogador";
|
String name = playerNames[playerId] ?? "Jogador";
|
||||||
|
|
||||||
matchShots.add(ShotRecord(
|
matchShots.add(ShotRecord(
|
||||||
relativeX: relativeX,
|
relativeX: relativeX, relativeY: relativeY, isMake: isMake,
|
||||||
relativeY: relativeY,
|
playerId: playerId, playerName: name, zone: zone, points: points
|
||||||
isMake: isMake,
|
|
||||||
playerId: playerId,
|
|
||||||
playerName: name,
|
|
||||||
zone: zone,
|
|
||||||
points: points
|
|
||||||
));
|
));
|
||||||
|
|
||||||
String finalAction = isMake ? "add_pts_$points" : "miss_$points";
|
String finalAction = isMake ? "add_pts_$points" : "miss_$points";
|
||||||
@@ -440,8 +436,11 @@ class PlacarController extends ChangeNotifier {
|
|||||||
int pts = int.parse(action.split("_").last);
|
int pts = int.parse(action.split("_").last);
|
||||||
if (isOpponent) opponentScore += pts; else myScore += pts;
|
if (isOpponent) opponentScore += pts; else myScore += pts;
|
||||||
stats["pts"] = stats["pts"]! + pts;
|
stats["pts"] = stats["pts"]! + pts;
|
||||||
if (pts == 2 || pts == 3) { stats["fgm"] = stats["fgm"]! + 1; stats["fga"] = stats["fga"]! + 1; }
|
|
||||||
|
if (pts == 2) { stats["fgm"] = stats["fgm"]! + 1; stats["fga"] = stats["fga"]! + 1; stats["p2m"] = stats["p2m"]! + 1; stats["p2a"] = stats["p2a"]! + 1; }
|
||||||
|
if (pts == 3) { stats["fgm"] = stats["fgm"]! + 1; stats["fga"] = stats["fga"]! + 1; stats["p3m"] = stats["p3m"]! + 1; stats["p3a"] = stats["p3a"]! + 1; }
|
||||||
if (pts == 1) { stats["ftm"] = stats["ftm"]! + 1; stats["fta"] = stats["fta"]! + 1; }
|
if (pts == 1) { stats["ftm"] = stats["ftm"]! + 1; stats["fta"] = stats["fta"]! + 1; }
|
||||||
|
|
||||||
logText = "marcou $pts pontos 🏀";
|
logText = "marcou $pts pontos 🏀";
|
||||||
}
|
}
|
||||||
else if (action.startsWith("sub_pts_")) {
|
else if (action.startsWith("sub_pts_")) {
|
||||||
@@ -449,9 +448,18 @@ class PlacarController extends ChangeNotifier {
|
|||||||
if (isOpponent) { opponentScore = (opponentScore - pts < 0) ? 0 : opponentScore - pts; }
|
if (isOpponent) { opponentScore = (opponentScore - pts < 0) ? 0 : opponentScore - pts; }
|
||||||
else { myScore = (myScore - pts < 0) ? 0 : myScore - pts; }
|
else { myScore = (myScore - pts < 0) ? 0 : myScore - pts; }
|
||||||
stats["pts"] = (stats["pts"]! - pts < 0) ? 0 : stats["pts"]! - pts;
|
stats["pts"] = (stats["pts"]! - pts < 0) ? 0 : stats["pts"]! - pts;
|
||||||
if (pts == 2 || pts == 3) {
|
|
||||||
|
if (pts == 2) {
|
||||||
if (stats["fgm"]! > 0) stats["fgm"] = stats["fgm"]! - 1;
|
if (stats["fgm"]! > 0) stats["fgm"] = stats["fgm"]! - 1;
|
||||||
if (stats["fga"]! > 0) stats["fga"] = stats["fga"]! - 1;
|
if (stats["fga"]! > 0) stats["fga"] = stats["fga"]! - 1;
|
||||||
|
if (stats["p2m"]! > 0) stats["p2m"] = stats["p2m"]! - 1;
|
||||||
|
if (stats["p2a"]! > 0) stats["p2a"] = stats["p2a"]! - 1;
|
||||||
|
}
|
||||||
|
if (pts == 3) {
|
||||||
|
if (stats["fgm"]! > 0) stats["fgm"] = stats["fgm"]! - 1;
|
||||||
|
if (stats["fga"]! > 0) stats["fga"] = stats["fga"]! - 1;
|
||||||
|
if (stats["p3m"]! > 0) stats["p3m"] = stats["p3m"]! - 1;
|
||||||
|
if (stats["p3a"]! > 0) stats["p3a"] = stats["p3a"]! - 1;
|
||||||
}
|
}
|
||||||
if (pts == 1) {
|
if (pts == 1) {
|
||||||
if (stats["ftm"]! > 0) stats["ftm"] = stats["ftm"]! - 1;
|
if (stats["ftm"]! > 0) stats["ftm"] = stats["ftm"]! - 1;
|
||||||
@@ -460,12 +468,12 @@ class PlacarController extends ChangeNotifier {
|
|||||||
logText = "teve $pts pontos retirados ❌";
|
logText = "teve $pts pontos retirados ❌";
|
||||||
}
|
}
|
||||||
else if (action == "miss_1") { stats["fta"] = stats["fta"]! + 1; logText = "falhou lance livre ❌"; }
|
else if (action == "miss_1") { stats["fta"] = stats["fta"]! + 1; logText = "falhou lance livre ❌"; }
|
||||||
else if (action == "miss_2" || action == "miss_3") { stats["fga"] = stats["fga"]! + 1; logText = "falhou lançamento ❌"; }
|
else if (action == "miss_2") { stats["fga"] = stats["fga"]! + 1; stats["p2a"] = stats["p2a"]! + 1; logText = "falhou lançamento de 2 ❌"; }
|
||||||
|
else if (action == "miss_3") { stats["fga"] = stats["fga"]! + 1; stats["p3a"] = stats["p3a"]! + 1; logText = "falhou lançamento de 3 ❌"; }
|
||||||
else if (action == "add_orb") { stats["orb"] = stats["orb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; logText = "ganhou ressalto ofensivo 🔄"; }
|
else if (action == "add_orb") { stats["orb"] = stats["orb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; logText = "ganhou ressalto ofensivo 🔄"; }
|
||||||
else if (action == "add_drb") { stats["drb"] = stats["drb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; logText = "ganhou ressalto defensivo 🛡️"; }
|
else if (action == "add_drb") { stats["drb"] = stats["drb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; logText = "ganhou ressalto defensivo 🛡️"; }
|
||||||
else if (action == "add_ast") {
|
else if (action == "add_ast") {
|
||||||
stats["ast"] = stats["ast"]! + 1;
|
stats["ast"] = stats["ast"]! + 1;
|
||||||
|
|
||||||
if (playByPlay.isNotEmpty && playByPlay[0].contains("marcou") && !playByPlay[0].contains("Assistência")) {
|
if (playByPlay.isNotEmpty && playByPlay[0].contains("marcou") && !playByPlay[0].contains("Assistência")) {
|
||||||
playByPlay[0] = "${playByPlay[0]} (Assistência: $name 🤝)";
|
playByPlay[0] = "${playByPlay[0]} (Assistência: $name 🤝)";
|
||||||
_saveLocalBackup();
|
_saveLocalBackup();
|
||||||
@@ -531,7 +539,6 @@ class PlacarController extends ChangeNotifier {
|
|||||||
if (mvpScore > maxMvpScore && mvpScore > 0) { maxMvpScore = mvpScore; mvpName = pName; }
|
if (mvpScore > maxMvpScore && mvpScore > 0) { maxMvpScore = mvpScore; mvpName = pName; }
|
||||||
});
|
});
|
||||||
|
|
||||||
// ATUALIZA O JOGO COM OS NOVOS ESTADOS E COM O HISTÓRICO DE JOGADAS!
|
|
||||||
await supabase.from('games').update({
|
await supabase.from('games').update({
|
||||||
'my_score': myScore,
|
'my_score': myScore,
|
||||||
'opponent_score': opponentScore,
|
'opponent_score': opponentScore,
|
||||||
@@ -545,7 +552,7 @@ class PlacarController extends ChangeNotifier {
|
|||||||
'top_rbs_name': topRbsName,
|
'top_rbs_name': topRbsName,
|
||||||
'top_def_name': topDefName,
|
'top_def_name': topDefName,
|
||||||
'mvp_name': mvpName,
|
'mvp_name': mvpName,
|
||||||
'play_by_play': playByPlay, // Envia o histórico para a base de dados
|
'play_by_play': playByPlay,
|
||||||
}).eq('id', gameId);
|
}).eq('id', gameId);
|
||||||
|
|
||||||
if (isGameFinishedNow && !gameWasAlreadyFinished && myTeamDbId != null && oppTeamDbId != null) {
|
if (isGameFinishedNow && !gameWasAlreadyFinished && myTeamDbId != null && oppTeamDbId != null) {
|
||||||
@@ -579,6 +586,7 @@ class PlacarController extends ChangeNotifier {
|
|||||||
batchStats.add({
|
batchStats.add({
|
||||||
'game_id': gameId, 'member_id': playerId, 'team_id': isMyTeamPlayer ? myTeamDbId! : oppTeamDbId!,
|
'game_id': gameId, 'member_id': playerId, 'team_id': isMyTeamPlayer ? myTeamDbId! : oppTeamDbId!,
|
||||||
'pts': stats['pts'], 'rbs': stats['rbs'], 'ast': stats['ast'], 'stl': stats['stl'], 'blk': stats['blk'], 'tov': stats['tov'], 'fls': stats['fls'], 'fgm': stats['fgm'], 'fga': stats['fga'], 'ftm': stats['ftm'], 'fta': stats['fta'], 'orb': stats['orb'], 'drb': stats['drb'],
|
'pts': stats['pts'], 'rbs': stats['rbs'], 'ast': stats['ast'], 'stl': stats['stl'], 'blk': stats['blk'], 'tov': stats['tov'], 'fls': stats['fls'], 'fgm': stats['fgm'], 'fga': stats['fga'], 'ftm': stats['ftm'], 'fta': stats['fta'], 'orb': stats['orb'], 'drb': stats['drb'],
|
||||||
|
'p2m': stats['p2m'], 'p2a': stats['p2a'], 'p3m': stats['p3m'], 'p3a': stats['p3a'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import '../controllers/team_controller.dart';
|
|||||||
import '../controllers/game_controller.dart';
|
import '../controllers/game_controller.dart';
|
||||||
import '../models/game_model.dart';
|
import '../models/game_model.dart';
|
||||||
import '../utils/size_extension.dart';
|
import '../utils/size_extension.dart';
|
||||||
|
import 'pdf_export_service.dart';
|
||||||
|
|
||||||
// --- CARD DE EXIBIÇÃO DO JOGO ---
|
|
||||||
class GameResultCard extends StatelessWidget {
|
class GameResultCard extends StatelessWidget {
|
||||||
final String gameId, myTeam, opponentTeam, myScore, opponentScore, status, season;
|
final String gameId, myTeam, opponentTeam, myScore, opponentScore, status, season;
|
||||||
final String? myTeamLogo, opponentTeamLogo;
|
final String? myTeamLogo, opponentTeamLogo;
|
||||||
@@ -44,13 +44,35 @@ class GameResultCard extends StatelessWidget {
|
|||||||
Expanded(child: _buildTeamInfo(opponentTeam, Colors.grey.shade600, opponentTeamLogo, sf, textColor)),
|
Expanded(child: _buildTeamInfo(opponentTeam, Colors.grey.shade600, opponentTeamLogo, sf, textColor)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
Positioned(
|
Positioned(
|
||||||
top: -10 * sf,
|
top: -10 * sf,
|
||||||
right: -10 * sf,
|
right: -10 * sf,
|
||||||
child: IconButton(
|
child: Row(
|
||||||
icon: Icon(Icons.delete_outline, color: Colors.grey.shade400, size: 22 * sf),
|
children: [
|
||||||
splashRadius: 20 * sf,
|
IconButton(
|
||||||
onPressed: () => _showDeleteConfirmation(context),
|
icon: Icon(Icons.picture_as_pdf, color: AppTheme.primaryRed.withOpacity(0.8), size: 22 * sf),
|
||||||
|
splashRadius: 20 * sf,
|
||||||
|
tooltip: 'Gerar PDF',
|
||||||
|
onPressed: () async {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('A gerar PDF...'), duration: Duration(seconds: 1)));
|
||||||
|
await PdfExportService.generateAndPrintBoxScore(
|
||||||
|
gameId: gameId,
|
||||||
|
myTeam: myTeam,
|
||||||
|
opponentTeam: opponentTeam,
|
||||||
|
myScore: myScore,
|
||||||
|
opponentScore: opponentScore,
|
||||||
|
season: season,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.delete_outline, color: Colors.grey.shade400, size: 22 * sf),
|
||||||
|
splashRadius: 20 * sf,
|
||||||
|
tooltip: 'Eliminar Jogo',
|
||||||
|
onPressed: () => _showDeleteConfirmation(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -141,7 +163,6 @@ class GameResultCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- POPUP DE CRIAÇÃO ---
|
|
||||||
class CreateGameDialogManual extends StatefulWidget {
|
class CreateGameDialogManual extends StatefulWidget {
|
||||||
final TeamController teamController;
|
final TeamController teamController;
|
||||||
final GameController gameController;
|
final GameController gameController;
|
||||||
@@ -280,7 +301,6 @@ class _CreateGameDialogManualState extends State<CreateGameDialogManual> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- PÁGINA PRINCIPAL DOS JOGOS ---
|
|
||||||
class GamePage extends StatefulWidget {
|
class GamePage extends StatefulWidget {
|
||||||
const GamePage({super.key});
|
const GamePage({super.key});
|
||||||
|
|
||||||
@@ -347,13 +367,11 @@ class _GamePageState extends State<GamePage> {
|
|||||||
myTeamLogo: myLogo,
|
myTeamLogo: myLogo,
|
||||||
opponentTeamLogo: oppLogo,
|
opponentTeamLogo: oppLogo,
|
||||||
sf: context.sf,
|
sf: context.sf,
|
||||||
onDelete: () async {
|
onDelete: () async {
|
||||||
bool success = await gameController.deleteGame(game.id);
|
bool success = await gameController.deleteGame(game.id);
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
if (success) {
|
if (success) {
|
||||||
// 👇 ISTO FORÇA A LISTA A ATUALIZAR IMEDIATAMENTE 👇
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Jogo eliminado com sucesso!'), backgroundColor: Colors.green)
|
const SnackBar(content: Text('Jogo eliminado com sucesso!'), backgroundColor: Colors.green)
|
||||||
);
|
);
|
||||||
|
|||||||
374
lib/pages/pdf_export_service.dart
Normal file
374
lib/pages/pdf_export_service.dart
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:pdf/pdf.dart';
|
||||||
|
import 'package:pdf/widgets.dart' as pw;
|
||||||
|
import 'package:printing/printing.dart';
|
||||||
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||||
|
|
||||||
|
class PdfExportService {
|
||||||
|
static Future<void> generateAndPrintBoxScore({
|
||||||
|
required String gameId,
|
||||||
|
required String myTeam,
|
||||||
|
required String opponentTeam,
|
||||||
|
required String myScore,
|
||||||
|
required String opponentScore,
|
||||||
|
required String season,
|
||||||
|
}) async {
|
||||||
|
final supabase = Supabase.instance.client;
|
||||||
|
|
||||||
|
final gameData = await supabase.from('games').select().eq('id', gameId).single();
|
||||||
|
|
||||||
|
final teamsData = await supabase.from('teams').select('id, name').inFilter('name', [myTeam, opponentTeam]);
|
||||||
|
String? myTeamId, oppTeamId;
|
||||||
|
for (var t in teamsData) {
|
||||||
|
if (t['name'] == myTeam) myTeamId = t['id'].toString();
|
||||||
|
if (t['name'] == opponentTeam) oppTeamId = t['id'].toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<dynamic> myPlayers = myTeamId != null ? await supabase.from('members').select().eq('team_id', myTeamId).eq('type', 'Jogador') : [];
|
||||||
|
List<dynamic> oppPlayers = oppTeamId != null ? await supabase.from('members').select().eq('team_id', oppTeamId).eq('type', 'Jogador') : [];
|
||||||
|
|
||||||
|
final statsData = await supabase.from('player_stats').select().eq('game_id', gameId);
|
||||||
|
Map<String, Map<String, dynamic>> statsMap = {};
|
||||||
|
for (var s in statsData) {
|
||||||
|
statsMap[s['member_id'].toString()] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<List<String>> myTeamTable = _buildTeamTableData(myPlayers, statsMap);
|
||||||
|
List<List<String>> oppTeamTable = _buildTeamTableData(oppPlayers, statsMap);
|
||||||
|
|
||||||
|
final pdf = pw.Document();
|
||||||
|
|
||||||
|
pdf.addPage(
|
||||||
|
pw.Page( // 1. Trocado de MultiPage para Page
|
||||||
|
pageFormat: PdfPageFormat.a4.landscape,
|
||||||
|
margin: const pw.EdgeInsets.all(16), // Margens ligeiramente reduzidas para aproveitar o espaço
|
||||||
|
build: (pw.Context context) {
|
||||||
|
// 2. Envolvemos tudo num FittedBox
|
||||||
|
return pw.FittedBox(
|
||||||
|
fit: pw.BoxFit.scaleDown, // Reduz o tamanho apenas se não couber na página
|
||||||
|
child: pw.Container(
|
||||||
|
// Fixamos a largura do contentor à largura útil da página
|
||||||
|
width: PdfPageFormat.a4.landscape.availableWidth,
|
||||||
|
// 3. Colocamos todos os elementos dentro de uma Column
|
||||||
|
child: pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
pw.Row(
|
||||||
|
mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
pw.Text('Relatório Estatístico', style: pw.TextStyle(fontSize: 24, fontWeight: pw.FontWeight.bold)),
|
||||||
|
pw.Column(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
pw.Text('$myTeam vs $opponentTeam', style: pw.TextStyle(fontSize: 16, fontWeight: pw.FontWeight.bold)),
|
||||||
|
pw.Text('Resultado: $myScore - $opponentScore', style: const pw.TextStyle(fontSize: 14)),
|
||||||
|
pw.Text('Época: $season', style: const pw.TextStyle(fontSize: 12)),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
),
|
||||||
|
pw.SizedBox(height: 15), // Espaçamentos verticais um pouco mais otimizados
|
||||||
|
|
||||||
|
pw.Text('Equipa: $myTeam', style: pw.TextStyle(fontSize: 14, fontWeight: pw.FontWeight.bold, color: const PdfColor.fromInt(0xFFA00000))),
|
||||||
|
pw.SizedBox(height: 4),
|
||||||
|
_buildPdfTable(myTeamTable, const PdfColor.fromInt(0xFFA00000)),
|
||||||
|
|
||||||
|
pw.SizedBox(height: 15),
|
||||||
|
|
||||||
|
pw.Text('Equipa: $opponentTeam', style: pw.TextStyle(fontSize: 14, fontWeight: pw.FontWeight.bold, color: PdfColors.grey700)),
|
||||||
|
pw.SizedBox(height: 4),
|
||||||
|
_buildPdfTable(oppTeamTable, PdfColors.grey700),
|
||||||
|
|
||||||
|
pw.SizedBox(height: 15),
|
||||||
|
|
||||||
|
pw.Row(
|
||||||
|
crossAxisAlignment: pw.CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildSummaryBox('Melhor Marcador', gameData['top_pts_name'] ?? '---'),
|
||||||
|
pw.SizedBox(width: 10),
|
||||||
|
_buildSummaryBox('Melhor Ressaltador', gameData['top_rbs_name'] ?? '---'),
|
||||||
|
pw.SizedBox(width: 10),
|
||||||
|
_buildSummaryBox('Melhor Passador', gameData['top_ast_name'] ?? '---'),
|
||||||
|
pw.SizedBox(width: 10),
|
||||||
|
_buildSummaryBox('MVP', gameData['mvp_name'] ?? '---'),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Printing.layoutPdf(
|
||||||
|
onLayout: (PdfPageFormat format) async => pdf.save(),
|
||||||
|
name: 'BoxScore_${myTeam}_vs_${opponentTeam}.pdf',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<List<String>> _buildTeamTableData(List<dynamic> players, Map<String, Map<String, dynamic>> statsMap) {
|
||||||
|
List<List<String>> tableData = [];
|
||||||
|
int tPts = 0, tFgm = 0, tFga = 0, tFtm = 0, tFta = 0, tFls = 0;
|
||||||
|
int tOrb = 0, tDrb = 0, tTr = 0, tStl = 0, tAst = 0, tTov = 0, tBlk = 0;
|
||||||
|
int tP3m = 0, tP2m = 0, tP3a = 0, tP2a = 0;
|
||||||
|
|
||||||
|
players.sort((a, b) {
|
||||||
|
int numA = int.tryParse(a['number']?.toString() ?? '0') ?? 0;
|
||||||
|
int numB = int.tryParse(b['number']?.toString() ?? '0') ?? 0;
|
||||||
|
return numA.compareTo(numB);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var p in players) {
|
||||||
|
String id = p['id'].toString();
|
||||||
|
String name = p['name'] ?? 'Desconhecido';
|
||||||
|
String number = p['number']?.toString() ?? '-';
|
||||||
|
|
||||||
|
var stat = statsMap[id] ?? {};
|
||||||
|
|
||||||
|
int pts = stat['pts'] ?? 0;
|
||||||
|
int fgm = stat['fgm'] ?? 0;
|
||||||
|
int fga = stat['fga'] ?? 0;
|
||||||
|
int ftm = stat['ftm'] ?? 0;
|
||||||
|
int fta = stat['fta'] ?? 0;
|
||||||
|
int p2m = stat['p2m'] ?? 0;
|
||||||
|
int p2a = stat['p2a'] ?? 0;
|
||||||
|
int p3m = stat['p3m'] ?? 0;
|
||||||
|
int p3a = stat['p3a'] ?? 0;
|
||||||
|
int fls = stat['fls'] ?? 0;
|
||||||
|
int orb = stat['orb'] ?? 0;
|
||||||
|
int drb = stat['drb'] ?? 0;
|
||||||
|
int tr = orb + drb;
|
||||||
|
int stl = stat['stl'] ?? 0;
|
||||||
|
int ast = stat['ast'] ?? 0;
|
||||||
|
int tov = stat['tov'] ?? 0;
|
||||||
|
int blk = stat['blk'] ?? 0;
|
||||||
|
|
||||||
|
tPts += pts; tFgm += fgm; tFga += fga; tFtm += ftm; tFta += fta;
|
||||||
|
tFls += fls; tOrb += orb; tDrb += drb; tTr += tr; tStl += stl;
|
||||||
|
tAst += ast; tTov += tov; tBlk += blk;
|
||||||
|
tP3m += p3m; tP2m += p2m; tP3a += p3a; tP2a += p2a;
|
||||||
|
|
||||||
|
String p2Pct = p2a > 0 ? ((p2m / p2a) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
String p3Pct = p3a > 0 ? ((p3m / p3a) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
String globalPct = fga > 0 ? ((fgm / fga) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
String llPct = fta > 0 ? ((ftm / fta) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
|
||||||
|
tableData.add([
|
||||||
|
number, name, pts.toString(),
|
||||||
|
p2m.toString(), p2a.toString(), p2Pct,
|
||||||
|
p3m.toString(), p3a.toString(), p3Pct,
|
||||||
|
fgm.toString(), fga.toString(), globalPct,
|
||||||
|
ftm.toString(), fta.toString(), llPct,
|
||||||
|
fls.toString(), orb.toString(), drb.toString(), tr.toString(),
|
||||||
|
stl.toString(), ast.toString(), tov.toString(), blk.toString()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tableData.isEmpty) {
|
||||||
|
tableData.add([
|
||||||
|
'-', 'Sem jogadores registados', '0',
|
||||||
|
'0', '0', '0%',
|
||||||
|
'0', '0', '0%',
|
||||||
|
'0', '0', '0%',
|
||||||
|
'0', '0', '0%',
|
||||||
|
'0', '0', '0', '0', '0', '0', '0', '0'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
String tP2Pct = tP2a > 0 ? ((tP2m / tP2a) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
String tP3Pct = tP3a > 0 ? ((tP3m / tP3a) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
String tGlobalPct = tFga > 0 ? ((tFgm / tFga) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
String tLlPct = tFta > 0 ? ((tFtm / tFta) * 100).toStringAsFixed(0) + '%' : '0%';
|
||||||
|
|
||||||
|
tableData.add([
|
||||||
|
'', 'TOTAIS', tPts.toString(),
|
||||||
|
tP2m.toString(), tP2a.toString(), tP2Pct,
|
||||||
|
tP3m.toString(), tP3a.toString(), tP3Pct,
|
||||||
|
tFgm.toString(), tFga.toString(), tGlobalPct,
|
||||||
|
tFtm.toString(), tFta.toString(), tLlPct,
|
||||||
|
tFls.toString(), tOrb.toString(), tDrb.toString(), tTr.toString(),
|
||||||
|
tStl.toString(), tAst.toString(), tTov.toString(), tBlk.toString()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return tableData;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _buildPdfTable(List<List<String>> data, PdfColor headerColor) {
|
||||||
|
final headerStyle = pw.TextStyle(color: PdfColors.white, fontWeight: pw.FontWeight.bold, fontSize: 8);
|
||||||
|
final subHeaderStyle = pw.TextStyle(color: PdfColors.white, fontWeight: pw.FontWeight.bold, fontSize: 7);
|
||||||
|
final cellStyle = const pw.TextStyle(fontSize: 8);
|
||||||
|
|
||||||
|
// Agora usamos apenas 15 colunas principais na tabela.
|
||||||
|
// Os grupos (2P, 3P, etc.) são subdivididos INTERNAMENTE para evitar erros de colSpan.
|
||||||
|
return pw.Table(
|
||||||
|
border: pw.TableBorder.all(color: PdfColors.grey400, width: 0.5),
|
||||||
|
columnWidths: {
|
||||||
|
0: const pw.FlexColumnWidth(1.2), // Nº
|
||||||
|
1: const pw.FlexColumnWidth(5.0), // NOME (Maior para caber nomes como S.Gilgeous-alexander)
|
||||||
|
2: const pw.FlexColumnWidth(1.5), // PT
|
||||||
|
3: const pw.FlexColumnWidth(4.5), // 2 PONTOS (Grupo de 3)
|
||||||
|
4: const pw.FlexColumnWidth(4.5), // 3 PONTOS (Grupo de 3)
|
||||||
|
5: const pw.FlexColumnWidth(4.5), // GLOBAL (Grupo de 3)
|
||||||
|
6: const pw.FlexColumnWidth(4.5), // L. LIVRES (Grupo de 3)
|
||||||
|
7: const pw.FlexColumnWidth(1.5), // FLS
|
||||||
|
8: const pw.FlexColumnWidth(1.5), // RO
|
||||||
|
9: const pw.FlexColumnWidth(1.5), // RD
|
||||||
|
10: const pw.FlexColumnWidth(1.5), // TR
|
||||||
|
11: const pw.FlexColumnWidth(1.5), // BR
|
||||||
|
12: const pw.FlexColumnWidth(1.5), // AS
|
||||||
|
13: const pw.FlexColumnWidth(1.5), // BP
|
||||||
|
14: const pw.FlexColumnWidth(1.5), // BLK
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
// --- LINHA 1: CABEÇALHOS ---
|
||||||
|
pw.TableRow(
|
||||||
|
decoration: pw.BoxDecoration(color: headerColor),
|
||||||
|
children: [
|
||||||
|
_simpleHeader('Nº', subHeaderStyle),
|
||||||
|
_simpleHeader('NOME', subHeaderStyle, align: pw.Alignment.centerLeft),
|
||||||
|
_simpleHeader('PT', subHeaderStyle),
|
||||||
|
_groupHeader('2 PONTOS', headerStyle, subHeaderStyle),
|
||||||
|
_groupHeader('3 PONTOS', headerStyle, subHeaderStyle),
|
||||||
|
_groupHeader('GLOBAL', headerStyle, subHeaderStyle),
|
||||||
|
_groupHeader('L. LIVRES', headerStyle, subHeaderStyle),
|
||||||
|
_simpleHeader('FLS', subHeaderStyle),
|
||||||
|
_simpleHeader('RO', subHeaderStyle),
|
||||||
|
_simpleHeader('RD', subHeaderStyle),
|
||||||
|
_simpleHeader('TR', subHeaderStyle),
|
||||||
|
_simpleHeader('BR', subHeaderStyle),
|
||||||
|
_simpleHeader('AS', subHeaderStyle),
|
||||||
|
_simpleHeader('BP', subHeaderStyle),
|
||||||
|
_simpleHeader('BLK', subHeaderStyle),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// --- LINHAS 2+: DADOS ---
|
||||||
|
...data.map((row) {
|
||||||
|
bool isTotais = row[1] == 'TOTAIS';
|
||||||
|
var rowStyle = isTotais ? pw.TextStyle(fontSize: 8, fontWeight: pw.FontWeight.bold) : cellStyle;
|
||||||
|
return pw.TableRow(
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
color: isTotais ? PdfColors.grey200 : PdfColors.white,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
_simpleData(row[0], rowStyle),
|
||||||
|
_simpleData(row[1], rowStyle, align: pw.Alignment.centerLeft),
|
||||||
|
_simpleData(row[2], rowStyle),
|
||||||
|
_groupData(row[3], row[4], row[5], rowStyle), // 2P: C, T, %
|
||||||
|
_groupData(row[6], row[7], row[8], rowStyle), // 3P: C, T, %
|
||||||
|
_groupData(row[9], row[10], row[11], rowStyle), // GLOBAL: C, T, %
|
||||||
|
_groupData(row[12], row[13], row[14], rowStyle), // L. LIVRES: C, T, %
|
||||||
|
_simpleData(row[15], rowStyle),
|
||||||
|
_simpleData(row[16], rowStyle),
|
||||||
|
_simpleData(row[17], rowStyle),
|
||||||
|
_simpleData(row[18], rowStyle),
|
||||||
|
_simpleData(row[19], rowStyle),
|
||||||
|
_simpleData(row[20], rowStyle),
|
||||||
|
_simpleData(row[21], rowStyle),
|
||||||
|
_simpleData(row[22], rowStyle),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== WIDGETS AUXILIARES PARA RESOLVER A ESTRUTURA DO PDF ====
|
||||||
|
|
||||||
|
// Cabeçalho simples (Colunas que não se dividem)
|
||||||
|
static pw.Widget _simpleHeader(String text, pw.TextStyle style, {pw.Alignment align = pw.Alignment.center}) {
|
||||||
|
return pw.Container(
|
||||||
|
alignment: align,
|
||||||
|
padding: const pw.EdgeInsets.symmetric(vertical: 2, horizontal: 2),
|
||||||
|
child: pw.Text(text, style: style),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dados simples
|
||||||
|
static pw.Widget _simpleData(String text, pw.TextStyle style, {pw.Alignment align = pw.Alignment.center}) {
|
||||||
|
return pw.Container(
|
||||||
|
alignment: align,
|
||||||
|
padding: const pw.EdgeInsets.symmetric(vertical: 3, horizontal: 2),
|
||||||
|
child: pw.Text(text, style: style),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cria a divisão do Cabeçalho (O falso ColSpan que une "2 PONTOS" sobre "C | T | %")
|
||||||
|
static pw.Widget _groupHeader(String title, pw.TextStyle hStyle, pw.TextStyle sStyle) {
|
||||||
|
return pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(
|
||||||
|
width: double.infinity,
|
||||||
|
alignment: pw.Alignment.center,
|
||||||
|
padding: const pw.EdgeInsets.symmetric(vertical: 2),
|
||||||
|
decoration: const pw.BoxDecoration(
|
||||||
|
border: pw.Border(bottom: pw.BorderSide(color: PdfColors.white, width: 0.5)),
|
||||||
|
),
|
||||||
|
child: pw.Text(title, style: hStyle),
|
||||||
|
),
|
||||||
|
pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Expanded(child: pw.Container(alignment: pw.Alignment.center, child: pw.Text('C', style: sStyle))),
|
||||||
|
pw.Container(width: 0.5, height: 10, color: PdfColors.white), // Divisória vertical manual
|
||||||
|
pw.Expanded(child: pw.Container(alignment: pw.Alignment.center, child: pw.Text('T', style: sStyle))),
|
||||||
|
pw.Container(width: 0.5, height: 10, color: PdfColors.white), // Divisória vertical manual
|
||||||
|
pw.Expanded(child: pw.Container(alignment: pw.Alignment.center, child: pw.Text('%', style: sStyle))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pw.Widget _groupData(String c, String t, String pct, pw.TextStyle style) {
|
||||||
|
return pw.Row(
|
||||||
|
children: [
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Container(
|
||||||
|
alignment: pw.Alignment.center,
|
||||||
|
padding: const pw.EdgeInsets.symmetric(vertical: 3),
|
||||||
|
child: pw.Text(c, style: style),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(width: 0.5, height: 12, color: PdfColors.grey400), // Divisória cinza
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Container(
|
||||||
|
alignment: pw.Alignment.center,
|
||||||
|
padding: const pw.EdgeInsets.symmetric(vertical: 3),
|
||||||
|
child: pw.Text(t, style: style),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pw.Container(width: 0.5, height: 12, color: PdfColors.grey400), // Divisória cinza
|
||||||
|
pw.Expanded(
|
||||||
|
child: pw.Container(
|
||||||
|
alignment: pw.Alignment.center,
|
||||||
|
padding: const pw.EdgeInsets.symmetric(vertical: 3),
|
||||||
|
child: pw.Text(pct, style: style),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
static pw.Widget _buildSummaryBox(String title, String value) {
|
||||||
|
return pw.Container(
|
||||||
|
width: 120,
|
||||||
|
decoration: pw.BoxDecoration(
|
||||||
|
border: pw.TableBorder.all(color: PdfColors.black, width: 1),
|
||||||
|
),
|
||||||
|
child: pw.Column(
|
||||||
|
children: [
|
||||||
|
pw.Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const pw.EdgeInsets.all(4),
|
||||||
|
color: const PdfColor.fromInt(0xFFA00000),
|
||||||
|
child: pw.Text(title, style: pw.TextStyle(color: PdfColors.white, fontSize: 9, fontWeight: pw.FontWeight.bold), textAlign: pw.TextAlign.center),
|
||||||
|
),
|
||||||
|
pw.Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const pw.EdgeInsets.all(6),
|
||||||
|
child: pw.Text(value, style: pw.TextStyle(fontSize: 10, fontWeight: pw.FontWeight.bold), textAlign: pw.TextAlign.center),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <file_selector_linux/file_selector_plugin.h>
|
#include <file_selector_linux/file_selector_plugin.h>
|
||||||
#include <gtk/gtk_plugin.h>
|
#include <gtk/gtk_plugin.h>
|
||||||
|
#include <printing/printing_plugin.h>
|
||||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||||
|
|
||||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||||
@@ -17,6 +18,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
|||||||
g_autoptr(FlPluginRegistrar) gtk_registrar =
|
g_autoptr(FlPluginRegistrar) gtk_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
|
||||||
gtk_plugin_register_with_registrar(gtk_registrar);
|
gtk_plugin_register_with_registrar(gtk_registrar);
|
||||||
|
g_autoptr(FlPluginRegistrar) printing_registrar =
|
||||||
|
fl_plugin_registry_get_registrar_for_plugin(registry, "PrintingPlugin");
|
||||||
|
printing_plugin_register_with_registrar(printing_registrar);
|
||||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
file_selector_linux
|
file_selector_linux
|
||||||
gtk
|
gtk
|
||||||
|
printing
|
||||||
url_launcher_linux
|
url_launcher_linux
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Foundation
|
|||||||
import app_links
|
import app_links
|
||||||
import file_selector_macos
|
import file_selector_macos
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
|
import printing
|
||||||
import shared_preferences_foundation
|
import shared_preferences_foundation
|
||||||
import sqflite_darwin
|
import sqflite_darwin
|
||||||
import url_launcher_macos
|
import url_launcher_macos
|
||||||
@@ -16,6 +17,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||||||
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
|
||||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
|
PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||||
|
|||||||
112
pubspec.lock
112
pubspec.lock
@@ -41,6 +41,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "1.0.4"
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.9"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -49,6 +57,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.0"
|
version: "2.13.0"
|
||||||
|
barcode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: barcode
|
||||||
|
sha256: "7b6729c37e3b7f34233e2318d866e8c48ddb46c1f7ad01ff7bb2a8de1da2b9f4"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.9"
|
||||||
|
bidi:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: bidi
|
||||||
|
sha256: "77f475165e94b261745cf1032c751e2032b8ed92ccb2bf5716036db79320637d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.13"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -85,10 +109,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -296,6 +320,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.8.0"
|
||||||
image_cropper:
|
image_cropper:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -436,18 +468,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.18"
|
version: "0.12.17"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.13.0"
|
version: "0.11.1"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -488,6 +520,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
path_parsing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_parsing
|
||||||
|
sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -536,6 +576,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.3.0"
|
||||||
|
pdf:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: pdf
|
||||||
|
sha256: e47a275b267873d5944ad5f5ff0dcc7ac2e36c02b3046a0ffac9b72fd362c44b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.12.0"
|
||||||
|
pdf_widget_wrapper:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pdf_widget_wrapper
|
||||||
|
sha256: c930860d987213a3d58c7ec3b7ecf8085c3897f773e8dc23da9cae60a5d6d0f5
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.2"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -560,6 +624,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
|
posix:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: posix
|
||||||
|
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.5.0"
|
||||||
postgrest:
|
postgrest:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -568,6 +640,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.0"
|
version: "2.6.0"
|
||||||
|
printing:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: printing
|
||||||
|
sha256: "689170c9ddb1bda85826466ba80378aa8993486d3c959a71cd7d2d80cb606692"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.14.3"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -576,6 +656,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.5+1"
|
version: "6.1.5+1"
|
||||||
|
qr:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: qr
|
||||||
|
sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
realtime_client:
|
realtime_client:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -785,10 +873,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
|
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.9"
|
version: "0.7.7"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -917,6 +1005,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "6.6.1"
|
||||||
yet_another_json_isolate:
|
yet_another_json_isolate:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ dependencies:
|
|||||||
shimmer: ^3.0.0
|
shimmer: ^3.0.0
|
||||||
cached_network_image: ^3.4.1
|
cached_network_image: ^3.4.1
|
||||||
shared_preferences: ^2.5.4
|
shared_preferences: ^2.5.4
|
||||||
|
printing: ^5.14.3
|
||||||
|
pdf: ^3.12.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <app_links/app_links_plugin_c_api.h>
|
#include <app_links/app_links_plugin_c_api.h>
|
||||||
#include <file_selector_windows/file_selector_windows.h>
|
#include <file_selector_windows/file_selector_windows.h>
|
||||||
|
#include <printing/printing_plugin.h>
|
||||||
#include <url_launcher_windows/url_launcher_windows.h>
|
#include <url_launcher_windows/url_launcher_windows.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
@@ -15,6 +16,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|||||||
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
|
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
|
||||||
FileSelectorWindowsRegisterWithRegistrar(
|
FileSelectorWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||||
|
PrintingPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("PrintingPlugin"));
|
||||||
UrlLauncherWindowsRegisterWithRegistrar(
|
UrlLauncherWindowsRegisterWithRegistrar(
|
||||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
app_links
|
app_links
|
||||||
file_selector_windows
|
file_selector_windows
|
||||||
|
printing
|
||||||
url_launcher_windows
|
url_launcher_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user