fix: signature card repository wrong API
This commit is contained in:
parent
4d2cd09adf
commit
545d3ad688
Binary file not shown.
|
|
@ -42,10 +42,12 @@ void main() {
|
|||
),
|
||||
documentRepositoryProvider.overrideWith(
|
||||
(ref) =>
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -4,16 +4,20 @@ import '../../domain/models/model.dart';
|
|||
class SignatureCardStateNotifier extends StateNotifier<List<SignatureCard>> {
|
||||
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<SignatureCard>.of(state);
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
final c = list[i];
|
||||
|
|
|
|||
|
|
@ -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<PdfMockContinuousList> {
|
|||
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<SignatureDragData>(
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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<PdfViewerWidget> {
|
|||
},
|
||||
),
|
||||
),
|
||||
// Drag target for dropping signatures
|
||||
Positioned.fill(
|
||||
child: DragTarget<SignatureDragData>(
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<SignatureCard>, `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,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <second_asset> on page <second_page>
|
||||
/// Usage: the user places a signature placement from asset <secondAsset> on page <secondPage>
|
||||
Future<void> theUserPlacesASignaturePlacementFromAssetOnPage(
|
||||
WidgetTester tester,
|
||||
String assetName,
|
||||
|
|
|
|||
|
|
@ -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 <first_asset> on page <first_page>
|
||||
And the user places a signature placement from asset <second_asset> on page <second_page>
|
||||
When the user places a signature placement from asset <firstAsset> on page <firstPage>.
|
||||
And the user places a signature placement from asset <secondAsset> on page <secondPage>.
|
||||
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 |
|
||||
|
|
|
|||
Loading…
Reference in New Issue