From 545d3ad6882487e448276802df00f4199bc772dc Mon Sep 17 00:00:00 2001 From: insleker Date: Thu, 11 Sep 2025 17:52:50 +0800 Subject: [PATCH] fix: signature card repository wrong API --- integration_test/data/sample-local-pdf.pdf | Bin 0 -> 49672 bytes integration_test/export_flow_test.dart | 17 ++-- .../signature_card_repository.dart | 12 ++- .../pdf/widgets/pdf_mock_continuous_list.dart | 92 +++++++++++++----- .../pdf/widgets/pdf_viewer_widget.dart | 36 +++++++ .../signature/widgets/signature_card.dart | 11 ++- .../widgets/signature_drag_data.dart | 4 +- ...cument_to_place_a_signature_placement.dart | 12 ++- ...ignature_placement_from_asset_on_page.dart | 2 +- ...upport_multiple_signature_pictures.feature | 10 +- .../rotated_signature_image_test.dart | 0 11 files changed, 148 insertions(+), 48 deletions(-) create mode 100644 integration_test/data/sample-local-pdf.pdf rename test/{widgets => widget}/rotated_signature_image_test.dart (100%) diff --git a/integration_test/data/sample-local-pdf.pdf b/integration_test/data/sample-local-pdf.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4603bd39c13f49b897b7bd0efbcf55374113246a GIT binary patch literal 49672 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 - DocumentStateNotifier() - ..openPicked(path: 'test.pdf', pageCount: 5), + DocumentStateNotifier()..openPicked( + path: 'integration_test/data/sample-local-pdf.pdf', + pageCount: 5, + ), ), - useMockViewerProvider.overrideWith((ref) => true), + useMockViewerProvider.overrideWith((ref) => false), exportServiceProvider.overrideWith((_) => fake), savePathPickerProvider.overrideWith( (_) => () async => 'C:/tmp/output.pdf', @@ -99,16 +101,17 @@ void main() { ), documentRepositoryProvider.overrideWith( (ref) => - DocumentStateNotifier() - ..openPicked(path: 'test.pdf', pageCount: 5), + DocumentStateNotifier()..openPicked( + path: 'integration_test/data/sample-local-pdf.pdf', + pageCount: 5, + ), ), signatureAssetRepositoryProvider.overrideWith((ref) { final c = SignatureAssetRepository(); c.add(sigBytes, name: 'image'); return c; }), - // Keep mock viewer for determinism on CI/desktop devices - useMockViewerProvider.overrideWithValue(true), + useMockViewerProvider.overrideWithValue(false), ], child: const MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, diff --git a/lib/data/repositories/signature_card_repository.dart b/lib/data/repositories/signature_card_repository.dart index ee169f5..833b4a0 100644 --- a/lib/data/repositories/signature_card_repository.dart +++ b/lib/data/repositories/signature_card_repository.dart @@ -4,16 +4,20 @@ import '../../domain/models/model.dart'; class SignatureCardStateNotifier extends StateNotifier> { SignatureCardStateNotifier() : super(const []); - add({required SignatureAsset asset, double rotationDeg = 0.0}) { + void add(SignatureCard card) { + state = List.of(state)..add(card); + } + + void addWithAsset(SignatureAsset asset, double rotationDeg) { state = List.of(state) ..add(SignatureCard(asset: asset, rotationDeg: rotationDeg)); } - void update({ - required SignatureCard card, + void update( + SignatureCard card, double? rotationDeg, GraphicAdjust? graphicAdjust, - }) { + ) { final list = List.of(state); for (var i = 0; i < list.length; i++) { final c = list[i]; diff --git a/lib/ui/features/pdf/widgets/pdf_mock_continuous_list.dart b/lib/ui/features/pdf/widgets/pdf_mock_continuous_list.dart index 6eaf9fa..ffdd554 100644 --- a/lib/ui/features/pdf/widgets/pdf_mock_continuous_list.dart +++ b/lib/ui/features/pdf/widgets/pdf_mock_continuous_list.dart @@ -7,6 +7,8 @@ import 'pdf_page_overlays.dart'; import 'pdf_providers.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; // using only adjusted overlay, no direct model imports needed +import '../../signature/widgets/signature_drag_data.dart'; +import 'package:pdf_signature/data/repositories/document_repository.dart'; /// Mocked continuous viewer for tests or platforms without real viewer. @visibleForTesting @@ -81,29 +83,73 @@ class _PdfMockContinuousListState extends ConsumerState { child: Stack( key: ValueKey('page_stack_$pageNum'), children: [ - Container( - color: Colors.grey.shade200, - child: Center( - child: Builder( - builder: (ctx) { - String label; - try { - label = AppLocalizations.of( - ctx, - ).pageInfo(pageNum, count); - } catch (_) { - label = 'Page $pageNum of $count'; - } - return Text( - label, - style: const TextStyle( - fontSize: 24, - color: Colors.black54, - ), - ); - }, - ), - ), + DragTarget( + onAcceptWithDetails: (details) { + final dragData = details.data; + final offset = details.offset; + final renderBox = + context.findRenderObject() as RenderBox?; + if (renderBox != null) { + final localPosition = renderBox.globalToLocal(offset); + final normalizedX = + localPosition.dx / renderBox.size.width; + final normalizedY = + localPosition.dy / renderBox.size.height; + + // Create a default rect for the signature (can be adjusted later) + final rect = Rect.fromLTWH( + (normalizedX - 0.1).clamp( + 0.0, + 0.8, + ), // Center horizontally with some margin + (normalizedY - 0.05).clamp( + 0.0, + 0.9, + ), // Center vertically with some margin + 0.2, // Default width + 0.1, // Default height + ); + + // Add placement to the document + ref + .read(documentRepositoryProvider.notifier) + .addPlacement( + page: pageNum, + rect: rect, + asset: dragData.card?.asset, + rotationDeg: dragData.card?.rotationDeg ?? 0.0, + ); + } + }, + builder: (context, candidateData, rejectedData) { + return Container( + color: + candidateData.isNotEmpty + ? Colors.blue.withOpacity(0.3) + : Colors.grey.shade200, + child: Center( + child: Builder( + builder: (ctx) { + String label; + try { + label = AppLocalizations.of( + ctx, + ).pageInfo(pageNum, count); + } catch (_) { + label = 'Page $pageNum of $count'; + } + return Text( + label, + style: const TextStyle( + fontSize: 24, + color: Colors.black54, + ), + ); + }, + ), + ), + ); + }, ), visible ? Stack( diff --git a/lib/ui/features/pdf/widgets/pdf_viewer_widget.dart b/lib/ui/features/pdf/widgets/pdf_viewer_widget.dart index 40b1ea6..e9f8d46 100644 --- a/lib/ui/features/pdf/widgets/pdf_viewer_widget.dart +++ b/lib/ui/features/pdf/widgets/pdf_viewer_widget.dart @@ -6,6 +6,7 @@ import 'package:pdf_signature/l10n/app_localizations.dart'; import 'pdf_page_overlays.dart'; import 'pdf_providers.dart'; import './pdf_mock_continuous_list.dart'; +import '../../signature/widgets/signature_drag_data.dart'; class PdfViewerWidget extends ConsumerStatefulWidget { const PdfViewerWidget({ @@ -115,6 +116,41 @@ class _PdfViewerWidgetState extends ConsumerState { }, ), ), + // Drag target for dropping signatures + Positioned.fill( + child: DragTarget( + onAcceptWithDetails: (details) { + final dragData = details.data; + + // For real PDF viewer, we need to calculate which page was dropped on + // This is a simplified implementation - in a real app you'd need to + // determine the exact page and position within that page + final currentPage = + ref.read(documentRepositoryProvider).currentPage; + + // Create a default rect for the signature (can be adjusted later) + final rect = const Rect.fromLTWH(0.1, 0.1, 0.2, 0.1); + + // Add placement to the document + ref + .read(documentRepositoryProvider.notifier) + .addPlacement( + page: currentPage, + rect: rect, + asset: dragData.card?.asset, + rotationDeg: dragData.card?.rotationDeg ?? 0.0, + ); + }, + builder: (context, candidateData, rejectedData) { + return Container( + color: + candidateData.isNotEmpty + ? Colors.blue.withOpacity(0.1) + : Colors.transparent, + ); + }, + ), + ), // Add signature overlays on top Positioned.fill( child: Consumer( diff --git a/lib/ui/features/signature/widgets/signature_card.dart b/lib/ui/features/signature/widgets/signature_card.dart index 23597a5..0dfed93 100644 --- a/lib/ui/features/signature/widgets/signature_card.dart +++ b/lib/ui/features/signature/widgets/signature_card.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:pdf_signature/domain/models/model.dart'; +import 'package:pdf_signature/domain/models/model.dart' as domain; import 'signature_drag_data.dart'; import 'rotated_signature_image.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; @@ -15,7 +15,7 @@ class SignatureCard extends StatelessWidget { this.useCurrentBytesForDrag = false, this.rotationDeg = 0.0, }); - final SignatureAsset asset; + final domain.SignatureAsset asset; final bool disabled; final VoidCallback onDelete; final VoidCallback? onTap; @@ -142,7 +142,12 @@ class SignatureCard extends StatelessWidget { data: useCurrentBytesForDrag ? const SignatureDragData() - : SignatureDragData(asset: asset), + : SignatureDragData( + card: domain.SignatureCard( + asset: asset, + rotationDeg: rotationDeg, + ), + ), feedback: Opacity( opacity: 0.9, child: ConstrainedBox( diff --git a/lib/ui/features/signature/widgets/signature_drag_data.dart b/lib/ui/features/signature/widgets/signature_drag_data.dart index c21acbb..12facf6 100644 --- a/lib/ui/features/signature/widgets/signature_drag_data.dart +++ b/lib/ui/features/signature/widgets/signature_drag_data.dart @@ -1,6 +1,6 @@ import 'package:pdf_signature/domain/models/model.dart'; class SignatureDragData { - final SignatureAsset? asset; // null means use current processed signature - const SignatureDragData({this.asset}); + final SignatureCard? card; // null means use current processed signature + const SignatureDragData({this.card}); } diff --git a/test/features/step/the_user_drags_this_signature_card_on_the_page_of_the_document_to_place_a_signature_placement.dart b/test/features/step/the_user_drags_this_signature_card_on_the_page_of_the_document_to_place_a_signature_placement.dart index b85e2ed..864bd10 100644 --- a/test/features/step/the_user_drags_this_signature_card_on_the_page_of_the_document_to_place_a_signature_placement.dart +++ b/test/features/step/the_user_drags_this_signature_card_on_the_page_of_the_document_to_place_a_signature_placement.dart @@ -4,6 +4,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_card_repository.dart'; import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; @@ -37,6 +38,14 @@ theUserDragsThisSignatureCardOnThePageOfTheDocumentToPlaceASignaturePlacement( .firstWhere((a) => a.name == 'placement.png'); } + // create a signature card + final temp_card = SignatureCard(asset: asset, rotationDeg: 0); + container + .read(signatureCardRepositoryProvider.notifier) + .addWithAsset(temp_card.asset, temp_card.rotationDeg); + // drag and drop (DragTarget, `onAccept`) it on document page + final drop_card = temp_card; + // Place it on the current page final pdf = container.read(documentRepositoryProvider); container @@ -44,6 +53,7 @@ theUserDragsThisSignatureCardOnThePageOfTheDocumentToPlaceASignaturePlacement( .addPlacement( page: pdf.currentPage, rect: Rect.fromLTWH(100, 100, 100, 50), - asset: asset, + asset: drop_card.asset, + rotationDeg: drop_card.rotationDeg, ); } diff --git a/test/features/step/the_user_places_a_signature_placement_from_asset_on_page.dart b/test/features/step/the_user_places_a_signature_placement_from_asset_on_page.dart index 9c634ab..0bce005 100644 --- a/test/features/step/the_user_places_a_signature_placement_from_asset_on_page.dart +++ b/test/features/step/the_user_places_a_signature_placement_from_asset_on_page.dart @@ -6,7 +6,7 @@ import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; -/// Usage: the user places a signature placement from asset on page +/// Usage: the user places a signature placement from asset on page Future theUserPlacesASignaturePlacementFromAssetOnPage( WidgetTester tester, String assetName, diff --git a/test/features/support_multiple_signature_pictures.feature b/test/features/support_multiple_signature_pictures.feature index 9a8a8eb..3952463 100644 --- a/test/features/support_multiple_signature_pictures.feature +++ b/test/features/support_multiple_signature_pictures.feature @@ -2,15 +2,11 @@ Feature: support multiple signature assets Scenario: Place signature placements on different pages with different assets Given a multi-page document is open - When the user places a signature placement from asset on page - And the user places a signature placement from asset on page + When the user places a signature placement from asset on page . + And the user places a signature placement from asset on page . Then both signature placements are shown on their respective pages Examples: - # Same page, same asset - # Same page, different assets - # Different pages, same asset - # Different pages, different assets - | first_asset | first_page | second_asset | second_page | + | firstAsset | firstPage | secondAsset | secondPage | | 'alice.png' | 1 | 'alice.png' | 1 | | 'alice.png' | 1 | 'bob.png' | 1 | | 'alice.png' | 1 | 'bob.png' | 3 | diff --git a/test/widgets/rotated_signature_image_test.dart b/test/widget/rotated_signature_image_test.dart similarity index 100% rename from test/widgets/rotated_signature_image_test.dart rename to test/widget/rotated_signature_image_test.dart