fix(frontend): CGU/PDF compatible Flutter 3.19 + pdfx 2.6 (build web Docker)

- Color.withOpacity à la place de withValues
- PdfViewPinch sans API absente (documentProgress, minScale)

Made-with: Cursor
This commit is contained in:
MARTIN Julien 2026-04-17 18:57:34 +02:00
parent f2daab1325
commit fc86181a73

View File

@ -137,7 +137,7 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
child: Material(
color: _ModaleCouleur.ivoire,
elevation: 6,
shadowColor: _ModaleCouleur.encre.withValues(alpha: 0.12),
shadowColor: _ModaleCouleur.encre.withOpacity(0.12),
child: SizedBox(
width: dialogW,
height: dialogH,
@ -179,9 +179,7 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
color: Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: _ModaleCouleur.turquoiseFonce.withValues(
alpha: 0.35,
),
color: _ModaleCouleur.turquoiseFonce.withOpacity(0.35),
),
),
child: ClipRRect(
@ -200,7 +198,7 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
'Document non disponible.',
style: GoogleFonts.merienda(
color: _ModaleCouleur.encre
.withValues(alpha: 0.75),
.withOpacity(0.75),
),
),
),
@ -221,9 +219,9 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
backgroundColor: _ModaleCouleur.turquoiseFonce,
foregroundColor: Colors.white,
disabledBackgroundColor:
_ModaleCouleur.mentheClair.withValues(alpha: 0.7),
_ModaleCouleur.mentheClair.withOpacity(0.7),
disabledForegroundColor:
_ModaleCouleur.encre.withValues(alpha: 0.45),
_ModaleCouleur.encre.withOpacity(0.45),
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 14,
@ -286,7 +284,7 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
tooltip: 'Fermer',
icon: Icon(
Icons.close,
color: _ModaleCouleur.encre.withValues(alpha: 0.55),
color: _ModaleCouleur.encre.withOpacity(0.55),
),
onPressed: () => Navigator.of(context).pop(false),
),
@ -311,7 +309,7 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
? _ModaleCouleur.turquoise
: _ModaleCouleur.mentheTresClair,
side: BorderSide(
color: _ModaleCouleur.turquoiseFonce.withValues(alpha: 0.55),
color: _ModaleCouleur.turquoiseFonce.withOpacity(0.55),
width: 1.5,
),
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 10),
@ -327,10 +325,8 @@ class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog>
}
}
/// [PdfViewPinch] sappuie sur un [InteractiveViewer], sans vrai [Scrollable] :
/// barre verticale reliée à [PdfControllerPinch.documentProgress] pour que le
/// « chariot » reste visible (surtout sur le web la barre OS est souvent
/// masquée).
/// [PdfViewPinch] pour le web / mobile (Flutter 3.19 + pdfx 2.6 : pas de
/// `documentProgress` / `minScale` comme sur les versions plus récentes).
class _PdfPaneWithScrollbar extends StatefulWidget {
const _PdfPaneWithScrollbar({
super.key,
@ -344,106 +340,27 @@ class _PdfPaneWithScrollbar extends StatefulWidget {
}
class _PdfPaneWithScrollbarState extends State<_PdfPaneWithScrollbar> {
static const double _barW = 14;
static const double _thumbW = 9;
static const double _minThumbH = 44;
late final PdfControllerPinch _ctrl;
@override
void initState() {
super.initState();
_ctrl = PdfControllerPinch(document: widget.documentFuture);
_ctrl.addListener(_onCtrl);
}
void _onCtrl() {
// [PdfViewPinch] met à jour documentProgress dans son propre listener :
// replanifier pour lire la valeur après ce tour de notifications.
Future.microtask(() {
if (mounted) setState(() {});
});
}
@override
void dispose() {
_ctrl.removeListener(_onCtrl);
_ctrl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final raw = _ctrl.documentProgress;
final safeP = (!raw.isFinite || raw.isNaN) ? 0.0 : raw.clamp(0.0, 1.0);
return Stack(
clipBehavior: Clip.hardEdge,
fit: StackFit.expand,
children: [
Padding(
padding: const EdgeInsets.only(right: _barW),
child: PdfViewPinch(
return PdfViewPinch(
padding: 10,
scrollDirection: Axis.vertical,
minScale: 1,
maxScale: 4,
controller: _ctrl,
backgroundDecoration: const BoxDecoration(color: Colors.white),
),
),
Positioned(
top: 6,
right: 1,
bottom: 6,
width: _barW,
child: LayoutBuilder(
builder: (context, c) {
final trackH = c.maxHeight;
final thumbH = (trackH * 0.2).clamp(_minThumbH, trackH * 0.5);
final maxTop = (trackH - thumbH).clamp(0.0, double.infinity);
final top = safeP * maxTop;
return Semantics(
label: 'Position dans le document',
child: Stack(
children: [
Positioned.fill(
child: DecoratedBox(
decoration: BoxDecoration(
color: _ModaleCouleur.turquoise.withValues(
alpha: 0.35,
),
borderRadius: BorderRadius.circular(8),
),
),
),
Positioned(
top: top,
left: (_barW - _thumbW) / 2,
child: Container(
width: _thumbW,
height: thumbH,
decoration: BoxDecoration(
color: _ModaleCouleur.turquoiseFonce,
borderRadius: BorderRadius.circular(_thumbW / 2),
boxShadow: const [
BoxShadow(
color: Color(0x40000000),
blurRadius: 3,
offset: Offset(0, 1),
),
],
),
),
),
],
),
);
},
),
),
],
);
}
}