Atualização de gauge

This commit is contained in:
Carlos Correia
2026-07-14 18:23:03 +01:00
parent 4fcf3a475a
commit 5b25d9bef4
22 changed files with 973 additions and 1441 deletions

View File

@@ -1,15 +1,29 @@
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lottie/lottie.dart';
import '../screens/video_screen.dart';
import '../widgets/entrance.dart';
import '../widgets/liquid_waves_background.dart';
import '../widgets/tap_bounce.dart';
typedef QuizNextBuilder =
Route<void> Function(BuildContext context, int nextScore);
Route<void> Function(BuildContext context, QuizScore nextScore);
/// Pontuação do quiz, separada em dois contadores independentes em vez de
/// uma única soma — cada pergunta soma 1 a exatamente um dos dois, nunca aos
/// dois nem a nenhum. Ver [QuizQuestionScreen.isSignQuestion].
class QuizScore {
const QuizScore({this.signs = 0, this.factors = 0});
final int signs;
final int factors;
QuizScore addSign(int amount) =>
QuizScore(signs: signs + amount, factors: factors);
QuizScore addFactor(int amount) =>
QuizScore(signs: signs, factors: factors + amount);
}
enum QuizAnswerType { text, image, number, yesNo }
@@ -56,7 +70,8 @@ class QuizQuestionScreen extends StatefulWidget {
required this.question,
required this.answers,
required this.nextRoute,
this.currentScore = 0,
this.currentScore = const QuizScore(),
this.isSignQuestion = false,
this.onFinished,
this.isFinal = false,
this.showBackButton = false,
@@ -76,7 +91,14 @@ class QuizQuestionScreen extends StatefulWidget {
final String question;
final List<QuizAnswer> answers;
final QuizNextBuilder nextRoute;
final int currentScore;
final QuizScore currentScore;
/// Quando true, uma resposta "de risco" (weight 2) soma a
/// [QuizScore.signs] em vez de [QuizScore.factors] — usado só nas 4
/// perguntas que representam sinais de má oclusão já instalados
/// (queixo, boca/dentição, apinhamento, céu da boca); todas as outras
/// contam como fatores de risco associados.
final bool isSignQuestion;
final VoidCallback? onFinished;
final bool isFinal;
final bool showBackButton;
@@ -169,27 +191,7 @@ class _QuizQuestionScreenState extends State<QuizQuestionScreen> {
clipBehavior: Clip.none,
children: [
Positioned.fill(child: Container(color: const Color(0xFFFAFAF7))),
Positioned(
left: -size.width * 0.40,
bottom: -size.width * 0.45,
child: IgnorePointer(
child: SizedBox(
width: size.width * 1.05,
height: size.width * 1.05,
child: Transform.rotate(
angle: 35 * math.pi / 180,
child: Opacity(
opacity: 0.95,
child: Lottie.asset(
'lottie/Liquid waves.json',
fit: BoxFit.cover,
repeat: true,
),
),
),
),
),
),
const LiquidWavesBackground(),
SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -477,10 +479,9 @@ class _QuizQuestionScreenState extends State<QuizQuestionScreen> {
// ser que a pergunta imponha um
// aspect ratio específico.
imageAspectRatio:
widget.answerImageAspectRatio ??
(widget
.answers
.length >=
widget
.answerImageAspectRatio ??
(widget.answers.length >=
3
? 2.3
: 1.5),
@@ -581,25 +582,30 @@ class _QuizQuestionScreenState extends State<QuizQuestionScreen> {
() => _navigating =
true,
);
int nextScore =
QuizScore nextScore =
widget.currentScore;
if (widget.answerType ==
if (widget.answerType !=
QuizAnswerType
.number) {
nextScore =
widget
.currentScore +
(_numberDontKnow
? 0
: (_numberValue ??
0));
} else {
final picked = widget
.answers[_selected!];
final increment =
picked.weight ==
2
? 1
: 0;
nextScore =
widget
.currentScore +
picked.weight;
widget.isSignQuestion
? widget
.currentScore
.addSign(
increment,
)
: widget
.currentScore
.addFactor(
increment,
);
}
if (widget.isFinal) {