diff --git a/docs/meta-arch.md b/docs/meta-arch.md index eb1710c..5c43048 100644 --- a/docs/meta-arch.md +++ b/docs/meta-arch.md @@ -7,7 +7,52 @@ ## Package structure -The repo structure follows official [Package structure](https://docs.flutter.dev/app-architecture/case-study#package-structure) with slight modifications. +The repo structure follows official [Package structure](https://docs.flutter.dev/app-architecture/case-study#package-structure). + +``` +lib +├─┬─ ui +│ ├─┬─ core +│ │ ├─┬─ ui +│ │ │ └─── +│ │ └─── themes +│ └─┬─ +│ ├─┬─ view_model +│ │ └─── .dart +│ └─┬─ widgets +│ ├── _screen.dart +│ └── +├─┬─ domain +│ └─┬─ models +│ └─── .dart +├─┬─ data +│ ├─┬─ repositories +│ │ └─── .dart +│ ├─┬─ services +│ │ └─── .dart +│ └─┬─ model +│ └─── .dart +├─── config +├─── utils +├─── routing +├─── main_staging.dart +├─── main_development.dart +└─── main.dart + +// The test folder contains unit and widget tests +test +├─── data +├─── domain +├─── ui +└─── utils + +// The testing folder contains mocks other classes need to execute tests +testing +├─── fakes +└─── models +``` + +But with slight modifications. * put each `/`s in `features/` sub-directory under `ui/`. * `test/features/` contains BDD unit tests for each feature. It focuses on pure logic, therefore will not access `View` but `ViewModel` and `Model`. @@ -21,15 +66,15 @@ Some rule of thumb: ### terminology -* signature asset +* `signature asset` * image file of a signature, stored in the device or cloud storage * can drawing from canvas -* signature card +* `signature card` * template of signature placement * It will include modifications such as brightness, contrast, background removal, rotation of the signature asset. -* signature placement +* `signature placement` * placed modified signature asset from signature card on a specific position on a specific page of a specific PDF document -* document +* `document` * PDF document to be signed ## key dependencies diff --git a/integration_test/export_flow_test.dart b/integration_test/export_flow_test.dart index 7266e05..8f370ff 100644 --- a/integration_test/export_flow_test.dart +++ b/integration_test/export_flow_test.dart @@ -7,7 +7,7 @@ import 'package:image/image.dart' as img; import 'package:pdf_signature/data/services/export_service.dart'; import 'package:pdf_signature/data/services/export_providers.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; @@ -32,8 +32,8 @@ void main() { await tester.pumpWidget( ProviderScope( overrides: [ - pdfProvider.overrideWith( - (ref) => PdfController()..openPicked(path: 'test.pdf'), + documentRepositoryProvider.overrideWith( + (ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'), ), signatureProvider.overrideWith( (ref) => SignatureController()..placeDefaultRect(), @@ -85,11 +85,11 @@ void main() { await tester.pumpWidget( ProviderScope( overrides: [ - pdfProvider.overrideWith( - (ref) => PdfController()..openPicked(path: 'test.pdf'), + documentRepositoryProvider.overrideWith( + (ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'), ), - signatureLibraryProvider.overrideWith((ref) { - final c = SignatureLibraryController(); + signatureAssetRepositoryProvider.overrideWith((ref) { + final c = SignatureAssetRepository(); c.add(sigBytes, name: 'image'); return c; }), @@ -121,11 +121,11 @@ void main() { final container = ProviderScope.containerOf(ctx); final sigState = container.read(signatureProvider); final r = sigState.rect!; - final lib = container.read(signatureLibraryProvider); + final lib = container.read(signatureAssetRepositoryProvider); final asset = lib.isNotEmpty ? lib.first : null; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement(page: pdf.currentPage, rect: r, asset: asset); container.read(signatureProvider.notifier).clearActiveOverlay(); await tester.pumpAndSettle(); diff --git a/lib/app.dart b/lib/app.dart index efa6fd4..aee5bb4 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -98,7 +98,7 @@ class _RootHomeSwitcher extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final pdf = ref.watch(pdfProvider); + final pdf = ref.watch(documentRepositoryProvider); if (!pdf.loaded) { return const WelcomeScreen(); } diff --git a/lib/data/model/model.dart b/lib/data/model/model.dart deleted file mode 100644 index 0e1c76d..0000000 --- a/lib/data/model/model.dart +++ /dev/null @@ -1,206 +0,0 @@ -import 'dart:typed_data'; -import 'package:flutter/widgets.dart'; - -/// A simple library of signature images available to the user in the sidebar. -class SignatureAsset { - final String id; // unique id - final Uint8List bytes; - // List>? strokes; - final String? name; // optional display name (e.g., filename) - const SignatureAsset({required this.id, required this.bytes, this.name}); -} - -class GraphicAdjust { - final double contrast; - final double brightness; - final bool bgRemoval; - - const GraphicAdjust({ - this.contrast = 1.0, - this.brightness = 0.0, - this.bgRemoval = false, - }); - - GraphicAdjust copyWith({ - double? contrast, - double? brightness, - bool? bgRemoval, - }) => GraphicAdjust( - contrast: contrast ?? this.contrast, - brightness: brightness ?? this.brightness, - bgRemoval: bgRemoval ?? this.bgRemoval, - ); -} - -/** - * signature card is template of signature placement - */ -class SignatureCard { - final double rotationDeg; - final SignatureAsset asset; - final GraphicAdjust graphicAdjust; - - const SignatureCard({ - required this.rotationDeg, - required this.asset, - this.graphicAdjust = const GraphicAdjust(), - }); - - SignatureCard copyWith({ - double? rotationDeg, - SignatureAsset? asset, - GraphicAdjust? graphicAdjust, - }) => SignatureCard( - rotationDeg: rotationDeg ?? this.rotationDeg, - asset: asset ?? this.asset, - graphicAdjust: graphicAdjust ?? this.graphicAdjust, - ); -} - -/// Represents a single signature placement on a page combining both the -/// geometric rectangle (UI coordinate space) and the signature asset -/// assigned to that placement. -class SignaturePlacement { - // The bounding box of this placement in UI coordinate space, implies scaling and position. - final Rect rect; - - /// Rotation in degrees to apply when rendering/exporting this placement. - final double rotationDeg; - final GraphicAdjust graphicAdjust; - final SignatureAsset asset; - - const SignaturePlacement({ - required this.rect, - required this.asset, - this.rotationDeg = 0.0, - this.graphicAdjust = const GraphicAdjust(), - }); - - SignaturePlacement copyWith({ - Rect? rect, - SignatureAsset? asset, - double? rotationDeg, - GraphicAdjust? graphicAdjust, - }) => SignaturePlacement( - rect: rect ?? this.rect, - asset: asset ?? this.asset, - rotationDeg: rotationDeg ?? this.rotationDeg, - graphicAdjust: graphicAdjust ?? this.graphicAdjust, - ); -} - -class PdfState { - final bool loaded; - final int pageCount; - final int currentPage; - final String? pickedPdfPath; - final Uint8List? pickedPdfBytes; - final int? signedPage; - // Multiple signature placements per page, each combines geometry and asset. - final Map> placementsByPage; - // UI state: selected placement index on the current page (if any) - final int? selectedPlacementIndex; - const PdfState({ - required this.loaded, - required this.pageCount, - required this.currentPage, - this.pickedPdfPath, - this.pickedPdfBytes, - this.signedPage, - this.placementsByPage = const {}, - this.selectedPlacementIndex, - }); - factory PdfState.initial() => const PdfState( - loaded: false, - pageCount: 0, - currentPage: 1, - pickedPdfBytes: null, - signedPage: null, - placementsByPage: {}, - selectedPlacementIndex: null, - ); - PdfState copyWith({ - bool? loaded, - int? pageCount, - int? currentPage, - String? pickedPdfPath, - Uint8List? pickedPdfBytes, - int? signedPage, - Map>? placementsByPage, - int? selectedPlacementIndex, - }) => PdfState( - loaded: loaded ?? this.loaded, - pageCount: pageCount ?? this.pageCount, - currentPage: currentPage ?? this.currentPage, - pickedPdfPath: pickedPdfPath ?? this.pickedPdfPath, - pickedPdfBytes: pickedPdfBytes ?? this.pickedPdfBytes, - signedPage: signedPage ?? this.signedPage, - placementsByPage: placementsByPage ?? this.placementsByPage, - selectedPlacementIndex: - selectedPlacementIndex ?? this.selectedPlacementIndex, - ); -} - -class SignatureState { - final Rect? rect; - final bool aspectLocked; - final bool bgRemoval; - final double contrast; - final double brightness; - // Rotation in degrees applied to the signature image when rendering/exporting - final double rotation; - final List> strokes; - final Uint8List? imageBytes; - // The signature asset the current overlay is based on (from library) - final SignatureAsset? asset; - // When true, the active signature overlay is movable/resizable and should not be exported. - // When false, the overlay is confirmed (unmovable) and eligible for export. - final bool editingEnabled; - const SignatureState({ - required this.rect, - required this.aspectLocked, - required this.bgRemoval, - required this.contrast, - required this.brightness, - this.rotation = 0.0, - required this.strokes, - this.imageBytes, - this.asset, - this.editingEnabled = false, - }); - factory SignatureState.initial() => const SignatureState( - rect: null, - aspectLocked: false, - bgRemoval: false, - contrast: 1.0, - brightness: 0.0, - rotation: 0.0, - strokes: [], - imageBytes: null, - asset: null, - editingEnabled: false, - ); - SignatureState copyWith({ - Rect? rect, - bool? aspectLocked, - bool? bgRemoval, - double? contrast, - double? brightness, - double? rotation, - List>? strokes, - Uint8List? imageBytes, - SignatureAsset? asset, - bool? editingEnabled, - }) => SignatureState( - rect: rect ?? this.rect, - aspectLocked: aspectLocked ?? this.aspectLocked, - bgRemoval: bgRemoval ?? this.bgRemoval, - contrast: contrast ?? this.contrast, - brightness: brightness ?? this.brightness, - rotation: rotation ?? this.rotation, - strokes: strokes ?? this.strokes, - imageBytes: imageBytes ?? this.imageBytes, - asset: asset ?? this.asset, - editingEnabled: editingEnabled ?? this.editingEnabled, - ); -} diff --git a/lib/data/repositories/pdf_repository.dart b/lib/data/repositories/pdf_repository.dart index 3ed97c8..73f2c9b 100644 --- a/lib/data/repositories/pdf_repository.dart +++ b/lib/data/repositories/pdf_repository.dart @@ -2,57 +2,39 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import '../../../../data/model/model.dart'; +import '../../domain/models/model.dart'; -class PdfController extends StateNotifier { - PdfController() : super(PdfState.initial()); - static const int samplePageCount = 5; +class DocumentStateNotifier extends StateNotifier { + DocumentStateNotifier() : super(Document.initial()); @visibleForTesting void openSample() { state = state.copyWith( loaded: true, - pageCount: samplePageCount, + pageCount: 5, currentPage: 1, - pickedPdfPath: null, - signedPage: null, placementsByPage: {}, - selectedPlacementIndex: null, ); } void openPicked({ required String path, - int pageCount = samplePageCount, + required int pageCount, Uint8List? bytes, }) { state = state.copyWith( loaded: true, pageCount: pageCount, currentPage: 1, - pickedPdfPath: path, pickedPdfBytes: bytes, - signedPage: null, placementsByPage: {}, - selectedPlacementIndex: null, ); } void jumpTo(int page) { if (!state.loaded) return; final clamped = page.clamp(1, state.pageCount); - state = state.copyWith(currentPage: clamped, selectedPlacementIndex: null); - } - - // Set or clear the page that will receive the signature overlay. - void setSignedPage(int? page) { - if (!state.loaded) return; - if (page == null) { - state = state.copyWith(signedPage: null, selectedPlacementIndex: null); - } else { - final clamped = page.clamp(1, state.pageCount); - state = state.copyWith(signedPage: clamped, selectedPlacementIndex: null); - } + state = state.copyWith(currentPage: clamped); } void setPageCount(int count) { @@ -80,7 +62,7 @@ class PdfController extends StateNotifier { ), ); map[p] = list; - state = state.copyWith(placementsByPage: map, selectedPlacementIndex: null); + state = state.copyWith(placementsByPage: map); } void updatePlacementRotation({ @@ -111,10 +93,7 @@ class PdfController extends StateNotifier { } else { map[p] = list; } - state = state.copyWith( - placementsByPage: map, - selectedPlacementIndex: null, - ); + state = state.copyWith(placementsByPage: map); } } @@ -142,27 +121,6 @@ class PdfController extends StateNotifier { ); } - void selectPlacement(int? index) { - if (!state.loaded) return; - // Only allow valid index on current page; otherwise clear - if (index == null) { - state = state.copyWith(selectedPlacementIndex: null); - return; - } - final list = state.placementsByPage[state.currentPage] ?? const []; - if (index >= 0 && index < list.length) { - state = state.copyWith(selectedPlacementIndex: index); - } else { - state = state.copyWith(selectedPlacementIndex: null); - } - } - - void deleteSelectedPlacement() { - final idx = state.selectedPlacementIndex; - if (idx == null) return; - removePlacement(page: state.currentPage, index: idx); - } - // NOTE: Programmatic reassignment of images has been removed. // Convenience to get asset for a placement @@ -173,6 +131,7 @@ class PdfController extends StateNotifier { } } -final pdfProvider = StateNotifierProvider( - (ref) => PdfController(), -); +final documentRepositoryProvider = + StateNotifierProvider( + (ref) => DocumentStateNotifier(), + ); diff --git a/lib/data/repositories/signature_library_repository.dart b/lib/data/repositories/signature_asset_repository.dart similarity index 68% rename from lib/data/repositories/signature_library_repository.dart rename to lib/data/repositories/signature_asset_repository.dart index efe5a35..fd405fd 100644 --- a/lib/data/repositories/signature_library_repository.dart +++ b/lib/data/repositories/signature_asset_repository.dart @@ -1,9 +1,10 @@ import 'dart:typed_data'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; -class SignatureLibraryController extends StateNotifier> { - SignatureLibraryController() : super(const []); +/// +class SignatureAssetRepository extends StateNotifier> { + SignatureAssetRepository() : super(const []); String add(Uint8List bytes, {String? name}) { // Always add a new asset (allow duplicates). This lets users create multiple cards @@ -27,7 +28,7 @@ class SignatureLibraryController extends StateNotifier> { } } -final signatureLibraryProvider = - StateNotifierProvider>( - (ref) => SignatureLibraryController(), +final signatureAssetRepositoryProvider = + StateNotifierProvider>( + (ref) => SignatureAssetRepository(), ); diff --git a/lib/data/repositories/signature_repository.dart b/lib/data/repositories/signature_repository.dart index e743202..cee68c9 100644 --- a/lib/data/repositories/signature_repository.dart +++ b/lib/data/repositories/signature_repository.dart @@ -6,15 +6,18 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:image/image.dart' as img; import 'package:pdf_signature/l10n/app_localizations.dart'; -import '../../../../data/model/model.dart'; +import '../../domain/models/model.dart'; import 'pdf_repository.dart'; -class SignatureController extends StateNotifier { - SignatureController() : super(SignatureState.initial()); +class SignatureController extends StateNotifier { + final Ref ref; + SignatureController(this.ref) : super(SignatureCard.initial()); static const Size pageSize = Size(400, 560); void resetForNewPage() { - state = SignatureState.initial(); + state = SignatureCard.initial(); + ref.read(currentRectProvider.notifier).setRect(null); + ref.read(editingEnabledProvider.notifier).set(false); } @visibleForTesting @@ -26,19 +29,22 @@ class SignatureController extends StateNotifier { final cy = pageSize.height * (0.1 + rand.nextDouble() * 0.8); Rect r = Rect.fromCenter(center: Offset(cx, cy), width: w, height: h); r = _clampRectToPage(r); - state = state.copyWith(rect: r, editingEnabled: true); + ref.read(currentRectProvider.notifier).setRect(r); + ref.read(editingEnabledProvider.notifier).set(true); } void loadSample() { final w = 120.0, h = 60.0; - state = state.copyWith( - rect: Rect.fromCenter( - center: Offset(pageSize.width / 2, pageSize.height * 0.75), - width: w, - height: h, - ), - editingEnabled: true, - ); + ref + .read(currentRectProvider.notifier) + .setRect( + Rect.fromCenter( + center: Offset(pageSize.width / 2, pageSize.height * 0.75), + width: w, + height: h, + ), + ); + ref.read(editingEnabledProvider.notifier).set(true); } void setInvalidSelected(BuildContext context) { @@ -56,17 +62,19 @@ class SignatureController extends StateNotifier { } void drag(Offset delta) { - if (state.rect == null || !state.editingEnabled) return; - final moved = state.rect!.shift(delta); - state = state.copyWith(rect: _clampRectToPage(moved)); + final currentRect = ref.read(currentRectProvider); + if (currentRect == null || !ref.read(editingEnabledProvider)) return; + final moved = currentRect.shift(delta); + ref.read(currentRectProvider.notifier).setRect(_clampRectToPage(moved)); } void resize(Offset delta) { - if (state.rect == null || !state.editingEnabled) return; - final r = state.rect!; + final currentRect = ref.read(currentRectProvider); + if (currentRect == null || !ref.read(editingEnabledProvider)) return; + final r = currentRect; double newW = r.width + delta.dx; double newH = r.height + delta.dy; - if (state.aspectLocked) { + if (ref.read(aspectLockedProvider)) { final aspect = r.width / r.height; // Keep ratio based on the dominant proportional delta final dxRel = (delta.dx / r.width).abs(); @@ -90,7 +98,7 @@ class SignatureController extends StateNotifier { newH *= minScale; Rect resized = Rect.fromLTWH(r.left, r.top, newW, newH); resized = _clampRectPositionToPage(resized); - state = state.copyWith(rect: resized); + ref.read(currentRectProvider.notifier).setRect(resized); return; } // Unlocked aspect: clamp each dimension independently @@ -98,7 +106,7 @@ class SignatureController extends StateNotifier { newH = newH.clamp(20.0, pageSize.height); Rect resized = Rect.fromLTWH(r.left, r.top, newW, newH); resized = _clampRectToPage(resized); - state = state.copyWith(rect: resized); + ref.read(currentRectProvider.notifier).setRect(resized); } Rect _clampRectToPage(Rect r) { @@ -116,89 +124,98 @@ class SignatureController extends StateNotifier { return Rect.fromLTWH(left, top, r.width, r.height); } - void toggleAspect(bool v) => state = state.copyWith(aspectLocked: v); - void setBgRemoval(bool v) => state = state.copyWith(bgRemoval: v); - void setContrast(double v) => state = state.copyWith(contrast: v); - void setBrightness(double v) => state = state.copyWith(brightness: v); - void setRotation(double deg) => state = state.copyWith(rotation: deg); + void toggleAspect(bool v) => ref.read(aspectLockedProvider.notifier).set(v); + void setBgRemoval(bool v) => + state = state.copyWith( + graphicAdjust: state.graphicAdjust.copyWith(bgRemoval: v), + ); + void setContrast(double v) => + state = state.copyWith( + graphicAdjust: state.graphicAdjust.copyWith(contrast: v), + ); + void setBrightness(double v) => + state = state.copyWith( + graphicAdjust: state.graphicAdjust.copyWith(brightness: v), + ); + void setRotation(double deg) => state = state.copyWith(rotationDeg: deg); - void setStrokes(List> strokes) => - state = state.copyWith(strokes: strokes); void ensureRectForStrokes() { - state = state.copyWith( - rect: - state.rect ?? - Rect.fromCenter( - center: Offset(pageSize.width / 2, pageSize.height * 0.75), - width: 140, - height: 70, - ), - editingEnabled: true, - ); + if (ref.read(currentRectProvider) == null) { + ref + .read(currentRectProvider.notifier) + .setRect( + Rect.fromCenter( + center: Offset(pageSize.width / 2, pageSize.height * 0.75), + width: 140, + height: 70, + ), + ); + ref.read(editingEnabledProvider.notifier).set(true); + } } void setImageBytes(Uint8List bytes) { - state = state.copyWith(imageBytes: bytes, asset: null); - if (state.rect == null) { + final newAsset = SignatureAsset(id: 'drawn', bytes: bytes); + state = state.copyWith(asset: newAsset); + if (ref.read(currentRectProvider) == null) { placeDefaultRect(); } - // Mark as draft/editable when user just loaded image - state = state.copyWith(editingEnabled: true); + ref.read(editingEnabledProvider.notifier).set(true); } // Select image from the shared signature library void setImageFromLibrary({required SignatureAsset asset}) { state = state.copyWith(asset: asset); - if (state.rect == null) { + if (ref.read(currentRectProvider) == null) { placeDefaultRect(); } - state = state.copyWith(editingEnabled: true); + ref.read(editingEnabledProvider.notifier).set(true); } void clearImage() { - state = state.copyWith(imageBytes: null, rect: null, editingEnabled: false); + state = SignatureCard.initial(); + ref.read(currentRectProvider.notifier).setRect(null); + ref.read(editingEnabledProvider.notifier).set(false); } void placeAtCenter(Offset center, {double width = 120, double height = 60}) { Rect r = Rect.fromCenter(center: center, width: width, height: height); r = _clampRectToPage(r); - state = state.copyWith(rect: r, editingEnabled: true); + ref.read(currentRectProvider.notifier).setRect(r); + ref.read(editingEnabledProvider.notifier).set(true); } // Confirm current signature: freeze editing and place it on the PDF as an immutable overlay. // Stores the placement rect in UI-space (SignatureController.pageSize units). // Returns the Rect placed, or null if no rect to confirm. Rect? confirmCurrentSignature(WidgetRef ref) { - final r = state.rect; + final r = ref.read(currentRectProvider); if (r == null) return null; // Place onto the current page - final pdf = ref.read(pdfProvider); + final pdf = ref.read(documentRepositoryProvider); if (!pdf.loaded) return null; - // Bind the processed image at placement time (so placed preview matches adjustments). - // If processed bytes exist, always create a new asset for this placement. - // Prefer reusing an existing library asset when the active overlay is - // based on a library item. If there is no library asset, do NOT create - // a new library card here — keep the placement's asset empty so the - // UI and exporter will fall back to using the processed/current bytes. - // Store as UI-space rect (consistent with export and rendering paths) ref - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: pdf.currentPage, rect: r, asset: state.asset, - rotationDeg: state.rotation, + rotationDeg: state.rotationDeg, ); // Newly placed index is the last one on the page final idx = - (ref.read(pdfProvider).placementsByPage[pdf.currentPage]?.length ?? 1) - + (ref + .read(documentRepositoryProvider) + .placementsByPage[pdf.currentPage] + ?.length ?? + 1) - 1; // Auto-select the newly placed item so the red box appears if (idx >= 0) { - ref.read(pdfProvider.notifier).selectPlacement(idx); + ref.read(documentRepositoryProvider.notifier).selectPlacement(idx); } // Freeze editing: keep rect for preview but disable interaction - state = state.copyWith(editingEnabled: false); + ref.read(editingEnabledProvider.notifier).set(false); return r; } @@ -206,76 +223,89 @@ class SignatureController extends StateNotifier { // Useful in widget tests where obtaining a WidgetRef is not straightforward. @visibleForTesting Rect? confirmCurrentSignatureWithContainer(ProviderContainer container) { - final r = state.rect; + final r = container.read(currentRectProvider); if (r == null) return null; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); if (!pdf.loaded) return null; - // Reuse existing library asset if present; otherwise leave empty so the - // placement will reference the current bytes via fallback paths. container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: pdf.currentPage, rect: r, asset: state.asset, - rotationDeg: state.rotation, + rotationDeg: state.rotationDeg, ); final idx = (container - .read(pdfProvider) + .read(documentRepositoryProvider) .placementsByPage[pdf.currentPage] ?.length ?? 1) - 1; // Auto-select the newly placed item so the red box appears if (idx >= 0) { - container.read(pdfProvider.notifier).selectPlacement(idx); + container.read(documentRepositoryProvider.notifier).selectPlacement(idx); } // Freeze editing: keep rect for preview but disable interaction - state = state.copyWith(editingEnabled: false); + container.read(editingEnabledProvider.notifier).set(false); return r; } // Remove the active overlay (draft or confirmed preview) but keep image settings intact void clearActiveOverlay() { - state = state.copyWith(rect: null, editingEnabled: false); + ref.read(currentRectProvider.notifier).setRect(null); + ref.read(editingEnabledProvider.notifier).set(false); } } -final signatureProvider = - StateNotifierProvider( - (ref) => SignatureController(), +final signatureCardProvider = + StateNotifierProvider( + (ref) => SignatureController(ref), ); +final currentRectProvider = StateNotifierProvider( + (ref) => RectNotifier(), +); + +class RectNotifier extends StateNotifier { + RectNotifier() : super(null); + + void setRect(Rect? r) => state = r; +} + +final editingEnabledProvider = StateNotifierProvider( + (ref) => BoolNotifier(false), +); + +class BoolNotifier extends StateNotifier { + BoolNotifier(bool initial) : super(initial); + + void set(bool v) => state = v; +} + +final aspectLockedProvider = StateNotifierProvider( + (ref) => BoolNotifier(false), +); + /// Derived provider that returns processed signature image bytes according to /// current adjustment settings (contrast/brightness) and background removal. /// Returns null if no image is loaded. The output is a PNG to preserve alpha. final processedSignatureImageProvider = Provider((ref) { - // Watch only the fields that affect pixel processing to avoid recompute on rotation. - final SignatureAsset? asset = ref.watch( - signatureProvider.select((s) => s.asset), - ); - final Uint8List? directBytes = ref.watch( - signatureProvider.select((s) => s.imageBytes), + final SignatureAsset asset = ref.watch( + signatureCardProvider.select((s) => s.asset), ); final double contrast = ref.watch( - signatureProvider.select((s) => s.contrast), + signatureCardProvider.select((s) => s.graphicAdjust.contrast), ); final double brightness = ref.watch( - signatureProvider.select((s) => s.brightness), + signatureCardProvider.select((s) => s.graphicAdjust.brightness), ); final bool bgRemoval = ref.watch( - signatureProvider.select((s) => s.bgRemoval), + signatureCardProvider.select((s) => s.graphicAdjust.bgRemoval), ); - // If active overlay is based on a library asset, pull its bytes - Uint8List? bytes; - if (asset != null) { - bytes = asset.bytes; - } else { - bytes = directBytes; - } - if (bytes == null || bytes.isEmpty) return null; + Uint8List? bytes = asset.bytes; + if (bytes.isEmpty) return null; // Decode (supports PNG/JPEG, etc.) final decoded = img.decodeImage(bytes); diff --git a/lib/data/services/export_service.dart b/lib/data/services/export_service.dart index b00d0f2..d284ee9 100644 --- a/lib/data/services/export_service.dart +++ b/lib/data/services/export_service.dart @@ -6,7 +6,7 @@ import 'package:pdf/widgets.dart' as pw; import 'package:pdf/pdf.dart' as pdf; import 'package:printing/printing.dart' as printing; import 'package:image/image.dart' as img; -import '../model/model.dart'; +import '../../domain/models/model.dart'; // NOTE: // - This exporter uses a raster snapshot of the UI (RepaintBoundary) and embeds it into a new PDF. diff --git a/lib/domain/models/document.dart b/lib/domain/models/document.dart new file mode 100644 index 0000000..95deb15 --- /dev/null +++ b/lib/domain/models/document.dart @@ -0,0 +1,39 @@ +import 'dart:typed_data'; +import 'signature_placement.dart'; + +/// PDF document to be signed +class Document { + final bool loaded; + final int pageCount; + final int currentPage; + final Uint8List? pickedPdfBytes; + // Multiple signature placements per page, each combines geometry and asset. + final Map> placementsByPage; + const Document({ + required this.loaded, + required this.pageCount, + required this.currentPage, + this.pickedPdfBytes, + this.placementsByPage = const {}, + }); + factory Document.initial() => const Document( + loaded: false, + pageCount: 0, + currentPage: 1, + pickedPdfBytes: null, + placementsByPage: {}, + ); + Document copyWith({ + bool? loaded, + int? pageCount, + int? currentPage, + Uint8List? pickedPdfBytes, + Map>? placementsByPage, + }) => Document( + loaded: loaded ?? this.loaded, + pageCount: pageCount ?? this.pageCount, + currentPage: currentPage ?? this.currentPage, + pickedPdfBytes: pickedPdfBytes ?? this.pickedPdfBytes, + placementsByPage: placementsByPage ?? this.placementsByPage, + ); +} diff --git a/lib/domain/models/graphic_adjust.dart b/lib/domain/models/graphic_adjust.dart new file mode 100644 index 0000000..ff5800b --- /dev/null +++ b/lib/domain/models/graphic_adjust.dart @@ -0,0 +1,21 @@ +class GraphicAdjust { + final double contrast; + final double brightness; + final bool bgRemoval; + + const GraphicAdjust({ + this.contrast = 1.0, + this.brightness = 0.0, + this.bgRemoval = false, + }); + + GraphicAdjust copyWith({ + double? contrast, + double? brightness, + bool? bgRemoval, + }) => GraphicAdjust( + contrast: contrast ?? this.contrast, + brightness: brightness ?? this.brightness, + bgRemoval: bgRemoval ?? this.bgRemoval, + ); +} diff --git a/lib/domain/models/model.dart b/lib/domain/models/model.dart new file mode 100644 index 0000000..9cffa74 --- /dev/null +++ b/lib/domain/models/model.dart @@ -0,0 +1,5 @@ +export 'signature_asset.dart'; +export 'graphic_adjust.dart'; +export 'signature_card.dart'; +export 'signature_placement.dart'; +export 'document.dart'; diff --git a/lib/domain/models/signature_asset.dart b/lib/domain/models/signature_asset.dart new file mode 100644 index 0000000..2ae6a59 --- /dev/null +++ b/lib/domain/models/signature_asset.dart @@ -0,0 +1,10 @@ +import 'dart:typed_data'; + +/// SignatureAsset store image file of a signature, stored in the device or cloud storage +class SignatureAsset { + final String id; // unique id + final Uint8List bytes; + // List>? strokes; + final String? name; // optional display name (e.g., filename) + const SignatureAsset({required this.id, required this.bytes, this.name}); +} diff --git a/lib/domain/models/signature_card.dart b/lib/domain/models/signature_card.dart new file mode 100644 index 0000000..f821b48 --- /dev/null +++ b/lib/domain/models/signature_card.dart @@ -0,0 +1,35 @@ +import 'dart:typed_data'; +import 'signature_asset.dart'; +import 'graphic_adjust.dart'; + +/** + * signature card is template of signature placement + * Use the [SignatureCardRepository] to obtain a full [SignatureCard] + */ +class SignatureCard { + final double rotationDeg; + final SignatureAsset asset; + final GraphicAdjust graphicAdjust; + + const SignatureCard({ + required this.rotationDeg, + required this.asset, + this.graphicAdjust = const GraphicAdjust(), + }); + + SignatureCard copyWith({ + double? rotationDeg, + SignatureAsset? asset, + GraphicAdjust? graphicAdjust, + }) => SignatureCard( + rotationDeg: rotationDeg ?? this.rotationDeg, + asset: asset ?? this.asset, + graphicAdjust: graphicAdjust ?? this.graphicAdjust, + ); + + factory SignatureCard.initial() => SignatureCard( + rotationDeg: 0.0, + asset: SignatureAsset(id: '', bytes: Uint8List(0)), + graphicAdjust: const GraphicAdjust(), + ); +} diff --git a/lib/domain/models/signature_placement.dart b/lib/domain/models/signature_placement.dart new file mode 100644 index 0000000..2317072 --- /dev/null +++ b/lib/domain/models/signature_placement.dart @@ -0,0 +1,35 @@ +import 'dart:ui'; +import 'signature_asset.dart'; +import 'graphic_adjust.dart'; + +/// Represents a single signature placement on a page combining both the +/// geometric rectangle (UI coordinate space) and the signature asset +/// assigned to that placement. +class SignaturePlacement { + // The bounding box of this placement in UI coordinate space, implies scaling and position. + final Rect rect; + + /// Rotation in degrees to apply when rendering/exporting this placement. + final double rotationDeg; + final GraphicAdjust graphicAdjust; + final SignatureAsset asset; + + const SignaturePlacement({ + required this.rect, + required this.asset, + this.rotationDeg = 0.0, + this.graphicAdjust = const GraphicAdjust(), + }); + + SignaturePlacement copyWith({ + Rect? rect, + SignatureAsset? asset, + double? rotationDeg, + GraphicAdjust? graphicAdjust, + }) => SignaturePlacement( + rect: rect ?? this.rect, + asset: asset ?? this.asset, + rotationDeg: rotationDeg ?? this.rotationDeg, + graphicAdjust: graphicAdjust ?? this.graphicAdjust, + ); +} diff --git a/lib/ui/features/pdf/widgets/adjustments_panel.dart b/lib/ui/features/pdf/widgets/adjustments_panel.dart index 02426c0..415502e 100644 --- a/lib/ui/features/pdf/widgets/adjustments_panel.dart +++ b/lib/ui/features/pdf/widgets/adjustments_panel.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; -import '../../../../data/model/model.dart'; +import '../../../../domain/models/model.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; class AdjustmentsPanel extends ConsumerWidget { const AdjustmentsPanel({super.key, required this.sig}); - final SignatureState sig; + final SignatureCard sig; @override Widget build(BuildContext context, WidgetRef ref) { @@ -22,19 +22,20 @@ class AdjustmentsPanel extends ConsumerWidget { children: [ Checkbox( key: const Key('chk_aspect_lock'), - value: sig.aspectLocked, + value: ref.watch(aspectLockedProvider), onChanged: (v) => ref - .read(signatureProvider.notifier) + .read(signatureCardProvider.notifier) .toggleAspect(v ?? false), ), Text(AppLocalizations.of(context).lockAspectRatio), const SizedBox(width: 16), Switch( key: const Key('swt_bg_removal'), - value: sig.bgRemoval, + value: sig.graphicAdjust.bgRemoval, onChanged: - (v) => ref.read(signatureProvider.notifier).setBgRemoval(v), + (v) => + ref.read(signatureCardProvider.notifier).setBgRemoval(v), ), Text(AppLocalizations.of(context).backgroundRemoval), ], @@ -47,15 +48,16 @@ class AdjustmentsPanel extends ConsumerWidget { Text(AppLocalizations.of(context).contrast), Align( alignment: Alignment.centerRight, - child: Text(sig.contrast.toStringAsFixed(2)), + child: Text(sig.graphicAdjust.contrast.toStringAsFixed(2)), ), Slider( key: const Key('sld_contrast'), min: 0.0, max: 2.0, - value: sig.contrast, + value: sig.graphicAdjust.contrast, onChanged: - (v) => ref.read(signatureProvider.notifier).setContrast(v), + (v) => + ref.read(signatureCardProvider.notifier).setContrast(v), ), ], ), @@ -66,15 +68,16 @@ class AdjustmentsPanel extends ConsumerWidget { Text(AppLocalizations.of(context).brightness), Align( alignment: Alignment.centerRight, - child: Text(sig.brightness.toStringAsFixed(2)), + child: Text(sig.graphicAdjust.brightness.toStringAsFixed(2)), ), Slider( key: const Key('sld_brightness'), min: -1.0, max: 1.0, - value: sig.brightness, + value: sig.graphicAdjust.brightness, onChanged: - (v) => ref.read(signatureProvider.notifier).setBrightness(v), + (v) => + ref.read(signatureCardProvider.notifier).setBrightness(v), ), ], ), diff --git a/lib/ui/features/pdf/widgets/pdf_page_area.dart b/lib/ui/features/pdf/widgets/pdf_page_area.dart index 0a97ed1..0f8e1f4 100644 --- a/lib/ui/features/pdf/widgets/pdf_page_area.dart +++ b/lib/ui/features/pdf/widgets/pdf_page_area.dart @@ -51,7 +51,7 @@ class _PdfPageAreaState extends ConsumerState { // is instructed to align to the provider's current page once ready. WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; - final pdf = ref.read(pdfProvider); + final pdf = ref.read(documentRepositoryProvider); if (pdf.pickedPdfPath != null && pdf.loaded) { _scrollToPage(pdf.currentPage); } @@ -68,7 +68,7 @@ class _PdfPageAreaState extends ConsumerState { void _scrollToPage(int page) { WidgetsBinding.instance.addPostFrameCallback((_) { if (!mounted) return; - final pdf = ref.read(pdfProvider); + final pdf = ref.read(documentRepositoryProvider); const isContinuous = true; // Real continuous: drive via PdfViewerController @@ -156,11 +156,11 @@ class _PdfPageAreaState extends ConsumerState { @override Widget build(BuildContext context) { - final pdf = ref.watch(pdfProvider); + final pdf = ref.watch(documentRepositoryProvider); const pageViewMode = 'continuous'; // React to provider currentPage changes (e.g., user tapped overview) - ref.listen(pdfProvider, (prev, next) { + ref.listen(documentRepositoryProvider, (prev, next) { if (_suppressProviderListen) return; if ((prev?.currentPage != next.currentPage)) { final target = next.currentPage; @@ -288,7 +288,9 @@ class _PdfPageAreaState extends ConsumerState { ], onViewerReady: (doc, controller) { if (pdf.pageCount != doc.pages.length) { - ref.read(pdfProvider.notifier).setPageCount(doc.pages.length); + ref + .read(documentRepositoryProvider.notifier) + .setPageCount(doc.pages.length); } final target = _pendingPage ?? pdf.currentPage; _pendingPage = null; @@ -305,9 +307,9 @@ class _PdfPageAreaState extends ConsumerState { // Programmatic navigation: wait until target reached if (_programmaticTargetPage != null) { if (n == _programmaticTargetPage) { - if (n != ref.read(pdfProvider).currentPage) { + if (n != ref.read(documentRepositoryProvider).currentPage) { _suppressProviderListen = true; - ref.read(pdfProvider.notifier).jumpTo(n); + ref.read(documentRepositoryProvider.notifier).jumpTo(n); WidgetsBinding.instance.addPostFrameCallback((_) { _suppressProviderListen = false; }); @@ -317,9 +319,9 @@ class _PdfPageAreaState extends ConsumerState { return; } // User scroll -> reflect page to provider without re-triggering scroll - if (n != ref.read(pdfProvider).currentPage) { + if (n != ref.read(documentRepositoryProvider).currentPage) { _suppressProviderListen = true; - ref.read(pdfProvider.notifier).jumpTo(n); + ref.read(documentRepositoryProvider.notifier).jumpTo(n); WidgetsBinding.instance.addPostFrameCallback((_) { _suppressProviderListen = false; }); @@ -348,8 +350,8 @@ class _PdfPageAreaState extends ConsumerState { } ref.read(signatureProvider.notifier).placeAtCenter(Offset(cx, cy)); ref - .read(pdfProvider.notifier) - .setSignedPage(ref.read(pdfProvider).currentPage); + .read(documentRepositoryProvider.notifier) + .setSignedPage(ref.read(documentRepositoryProvider).currentPage); }, builder: (context, candidateData, rejected) => Stack( diff --git a/lib/ui/features/pdf/widgets/pdf_page_overlays.dart b/lib/ui/features/pdf/widgets/pdf_page_overlays.dart index c99cd1b..d7f70c9 100644 --- a/lib/ui/features/pdf/widgets/pdf_page_overlays.dart +++ b/lib/ui/features/pdf/widgets/pdf_page_overlays.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; -import '../../../../data/model/model.dart'; +import '../../../../domain/models/model.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'signature_overlay.dart'; @@ -29,8 +29,8 @@ class PdfPageOverlays extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final pdf = ref.watch(pdfProvider); - final sig = ref.watch(signatureProvider); + final pdf = ref.watch(documentRepositoryProvider); + final sig = ref.watch(signatureCardProvider); final placed = pdf.placementsByPage[pageNumber] ?? const []; final widgets = []; @@ -44,16 +44,17 @@ class PdfPageOverlays extends ConsumerWidget { rect: uiRect, sig: sig, pageNumber: pageNumber, - interactive: false, placedIndex: i, onSelectPlaced: onSelectPlaced, ), ); } + final currentRect = ref.watch(currentRectProvider); + final editingEnabled = ref.watch(editingEnabledProvider); final showActive = - sig.rect != null && - sig.editingEnabled && + currentRect != null && + editingEnabled && (pdf.signedPage == null || pdf.signedPage == pageNumber) && pdf.currentPage == pageNumber; @@ -61,10 +62,9 @@ class PdfPageOverlays extends ConsumerWidget { widgets.add( SignatureOverlay( pageSize: pageSize, - rect: sig.rect!, + rect: currentRect, sig: sig, pageNumber: pageNumber, - interactive: true, onDragSignature: onDragSignature, onResizeSignature: onResizeSignature, onConfirmSignature: onConfirmSignature, diff --git a/lib/ui/features/pdf/widgets/pdf_pages_overview.dart b/lib/ui/features/pdf/widgets/pdf_pages_overview.dart index 0ddd2f3..d2c6452 100644 --- a/lib/ui/features/pdf/widgets/pdf_pages_overview.dart +++ b/lib/ui/features/pdf/widgets/pdf_pages_overview.dart @@ -10,7 +10,7 @@ class PdfPagesOverview extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final pdf = ref.watch(pdfProvider); + final pdf = ref.watch(documentRepositoryProvider); final useMock = ref.watch(useMockViewerProvider); final theme = Theme.of(context); @@ -25,7 +25,10 @@ class PdfPagesOverview extends ConsumerWidget { final pageNumber = index + 1; final isSelected = pdf.currentPage == pageNumber; return InkWell( - onTap: () => ref.read(pdfProvider.notifier).jumpTo(pageNumber), + onTap: + () => ref + .read(documentRepositoryProvider.notifier) + .jumpTo(pageNumber), child: DecoratedBox( decoration: BoxDecoration( color: @@ -74,7 +77,9 @@ class PdfPagesOverview extends ConsumerWidget { final pages = document.pages; if (pdf.pageCount != pages.length) { WidgetsBinding.instance.addPostFrameCallback((_) { - ref.read(pdfProvider.notifier).setPageCount(pages.length); + ref + .read(documentRepositoryProvider.notifier) + .setPageCount(pages.length); }); } return buildList( diff --git a/lib/ui/features/pdf/widgets/pdf_screen.dart b/lib/ui/features/pdf/widgets/pdf_screen.dart index e428159..0855bed 100644 --- a/lib/ui/features/pdf/widgets/pdf_screen.dart +++ b/lib/ui/features/pdf/widgets/pdf_screen.dart @@ -12,7 +12,7 @@ import '../../../../data/services/export_providers.dart'; import 'package:image/image.dart' as img; import 'package:pdf_signature/data/repositories/signature_repository.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'draw_canvas.dart'; import 'pdf_toolbar.dart'; import 'pdf_page_area.dart'; @@ -61,13 +61,15 @@ class _PdfSignatureHomePageState extends ConsumerState { } catch (_) { bytes = null; } - ref.read(pdfProvider.notifier).openPicked(path: file.path, bytes: bytes); + ref + .read(documentRepositoryProvider.notifier) + .openPicked(path: file.path, bytes: bytes); ref.read(signatureProvider.notifier).resetForNewPage(); } } void _jumpToPage(int page) { - ref.read(pdfProvider.notifier).jumpTo(page); + ref.read(documentRepositoryProvider.notifier).jumpTo(page); } Future _loadSignatureFromFile() async { @@ -81,9 +83,11 @@ class _PdfSignatureHomePageState extends ConsumerState { final bytes = await file.readAsBytes(); final sig = ref.read(signatureProvider.notifier); sig.setImageBytes(bytes); - final p = ref.read(pdfProvider); + final p = ref.read(documentRepositoryProvider); if (p.loaded) { - ref.read(pdfProvider.notifier).setSignedPage(p.currentPage); + ref + .read(documentRepositoryProvider.notifier) + .setSignedPage(p.currentPage); } return bytes; } @@ -101,7 +105,7 @@ class _PdfSignatureHomePageState extends ConsumerState { } void _onSelectPlaced(int? index) { - ref.read(pdfProvider.notifier).selectPlacement(index); + ref.read(documentRepositoryProvider.notifier).selectPlacement(index); } Future _openDrawCanvas() async { @@ -113,9 +117,11 @@ class _PdfSignatureHomePageState extends ConsumerState { ); if (result != null && result.isNotEmpty) { ref.read(signatureProvider.notifier).setImageBytes(result); - final p = ref.read(pdfProvider); + final p = ref.read(documentRepositoryProvider); if (p.loaded) { - ref.read(pdfProvider.notifier).setSignedPage(p.currentPage); + ref + .read(documentRepositoryProvider.notifier) + .setSignedPage(p.currentPage); } } return result; @@ -124,7 +130,7 @@ class _PdfSignatureHomePageState extends ConsumerState { Future _saveSignedPdf() async { ref.read(exportingProvider.notifier).state = true; try { - final pdf = ref.read(pdfProvider); + final pdf = ref.read(documentRepositoryProvider); final sig = ref.read(signatureProvider); final messenger = ScaffoldMessenger.of(context); if (!pdf.loaded || sig.rect == null) { @@ -175,7 +181,8 @@ class _PdfSignatureHomePageState extends ConsumerState { signatureImageBytes: rotated, placementsByPage: pdf.placementsByPage, libraryBytes: { - for (final a in ref.read(signatureLibraryProvider)) a.id: a.bytes, + for (final a in ref.read(signatureAssetRepositoryProvider)) + a.id: a.bytes, }, targetDpi: targetDpi, ); @@ -211,7 +218,8 @@ class _PdfSignatureHomePageState extends ConsumerState { signatureImageBytes: rotated, placementsByPage: pdf.placementsByPage, libraryBytes: { - for (final a in ref.read(signatureLibraryProvider)) a.id: a.bytes, + for (final a in ref.read(signatureAssetRepositoryProvider)) + a.id: a.bytes, }, targetDpi: targetDpi, ); @@ -241,7 +249,7 @@ class _PdfSignatureHomePageState extends ConsumerState { signatureImageBytes: rotated, placementsByPage: pdf.placementsByPage, libraryBytes: { - for (final a in ref.read(signatureLibraryProvider)) + for (final a in ref.read(signatureAssetRepositoryProvider)) a.id: a.bytes, }, targetDpi: targetDpi, @@ -411,7 +419,7 @@ class _PdfSignatureHomePageState extends ConsumerState { }); }, zoomLevel: _zoomLevel, - fileName: ref.watch(pdfProvider).pickedPdfPath, + fileName: ref.watch(documentRepositoryProvider).pickedPdfPath, showPagesSidebar: _showPagesSidebar, showSignaturesSidebar: _showSignaturesSidebar, onTogglePagesSidebar: diff --git a/lib/ui/features/pdf/widgets/pdf_toolbar.dart b/lib/ui/features/pdf/widgets/pdf_toolbar.dart index f8bb7af..4e40d41 100644 --- a/lib/ui/features/pdf/widgets/pdf_toolbar.dart +++ b/lib/ui/features/pdf/widgets/pdf_toolbar.dart @@ -55,7 +55,7 @@ class _PdfToolbarState extends ConsumerState { @override Widget build(BuildContext context) { - final pdf = ref.watch(pdfProvider); + final pdf = ref.watch(documentRepositoryProvider); final l = AppLocalizations.of(context); final pageInfo = l.pageInfo(pdf.currentPage, pdf.pageCount); diff --git a/lib/ui/features/pdf/widgets/signature_drawer.dart b/lib/ui/features/pdf/widgets/signature_drawer.dart index 9c5d19b..fd7e32e 100644 --- a/lib/ui/features/pdf/widgets/signature_drawer.dart +++ b/lib/ui/features/pdf/widgets/signature_drawer.dart @@ -2,11 +2,11 @@ import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; -import 'package:pdf_signature/data/model/model.dart' as model; +import 'package:pdf_signature/domain/models/model.dart' as model; import '../../../../data/services/export_providers.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'image_editor_dialog.dart'; import '../../signature/widgets/signature_card.dart'; @@ -37,7 +37,7 @@ class _SignatureDrawerState extends ConsumerState { final sig = ref.watch(signatureProvider); final processed = ref.watch(processedSignatureImageProvider); final bytes = processed ?? sig.imageBytes; - final library = ref.watch(signatureLibraryProvider); + final library = ref.watch(signatureAssetRepositoryProvider); final isExporting = ref.watch(exportingProvider); final disabled = widget.disabled || isExporting; @@ -64,7 +64,7 @@ class _SignatureDrawerState extends ConsumerState { disabled: disabled, onDelete: () => ref - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .remove(a.id), onAdjust: () async { ref @@ -151,10 +151,16 @@ class _SignatureDrawerState extends ConsumerState { ref.read(signatureProvider).imageBytes; if (b != null) { final id = ref - .read(signatureLibraryProvider.notifier) + .read( + signatureAssetRepositoryProvider + .notifier, + ) .add(b, name: 'image'); final asset = ref - .read(signatureLibraryProvider.notifier) + .read( + signatureAssetRepositoryProvider + .notifier, + ) .byId(id); if (asset != null) { ref @@ -179,10 +185,16 @@ class _SignatureDrawerState extends ConsumerState { ref.read(signatureProvider).imageBytes; if (b != null) { final id = ref - .read(signatureLibraryProvider.notifier) + .read( + signatureAssetRepositoryProvider + .notifier, + ) .add(b, name: 'drawing'); final asset = ref - .read(signatureLibraryProvider.notifier) + .read( + signatureAssetRepositoryProvider + .notifier, + ) .byId(id); if (asset != null) { ref diff --git a/lib/ui/features/pdf/widgets/signature_overlay.dart b/lib/ui/features/pdf/widgets/signature_overlay.dart index 06d2394..f4cce60 100644 --- a/lib/ui/features/pdf/widgets/signature_overlay.dart +++ b/lib/ui/features/pdf/widgets/signature_overlay.dart @@ -4,10 +4,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; -import '../../../../data/model/model.dart'; +import '../../../../domain/models/model.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'image_editor_dialog.dart'; import '../../signature/widgets/rotated_signature_image.dart'; @@ -19,7 +19,6 @@ class SignatureOverlay extends ConsumerWidget { required this.rect, required this.sig, required this.pageNumber, - this.interactive = true, this.placedIndex, this.onDragSignature, this.onResizeSignature, @@ -30,9 +29,8 @@ class SignatureOverlay extends ConsumerWidget { final Size pageSize; final Rect rect; - final SignatureState sig; + final SignatureCard sig; final int pageNumber; - final bool interactive; final int? placedIndex; // Callbacks used by interactive overlay @@ -75,7 +73,8 @@ class SignatureOverlay extends ConsumerWidget { double scaleX, double scaleY, ) { - final selectedIdx = ref.read(pdfProvider).selectedPlacementIndex; + final selectedIdx = + ref.read(documentRepositoryProvider).selectedPlacementIndex; final bool isPlaced = placedIndex != null; final bool isSelected = isPlaced && selectedIdx == placedIndex; final Color borderColor = isPlaced ? Colors.red : Colors.indigo; @@ -92,7 +91,7 @@ class SignatureOverlay extends ConsumerWidget { 0, 0, 0, - 0.05 + math.min(0.25, (sig.contrast - 1.0).abs()), + 0.05 + math.min(0.25, (sig.graphicAdjust.contrast - 1.0).abs()), ), ), ), @@ -210,7 +209,7 @@ class SignatureOverlay extends ConsumerWidget { onClearActiveOverlay?.call(); } else { ref - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .removePlacement(page: pageNumber, index: placedIndex); } } else if (choice == 'adjust') { @@ -231,23 +230,24 @@ class _SignatureImage extends ConsumerWidget { final bool interactive; final int? placedIndex; final int pageNumber; - final SignatureState sig; + final SignatureCard sig; @override Widget build(BuildContext context, WidgetRef ref) { Uint8List? bytes; if (interactive) { final processed = ref.watch(processedSignatureImageProvider); - bytes = processed ?? sig.imageBytes; + bytes = processed ?? sig.asset.bytes; } else if (placedIndex != null) { - final placementList = ref.read(pdfProvider).placementsByPage[pageNumber]; + final placementList = + ref.read(documentRepositoryProvider).placementsByPage[pageNumber]; final placement = (placementList != null && placedIndex! < placementList.length) ? placementList[placedIndex!] : null; final imgId = (placement?.asset)?.id; if (imgId != null && imgId.isNotEmpty) { - final lib = ref.watch(signatureLibraryProvider); + final lib = ref.watch(signatureAssetRepositoryProvider); for (final a in lib) { if (a.id == imgId) { bytes = a.bytes; @@ -255,7 +255,7 @@ class _SignatureImage extends ConsumerWidget { } } } - bytes ??= ref.read(processedSignatureImageProvider) ?? sig.imageBytes; + bytes ??= ref.read(processedSignatureImageProvider) ?? sig.asset.bytes; } if (bytes == null) { @@ -271,9 +271,10 @@ class _SignatureImage extends ConsumerWidget { // Use live rotation for interactive overlay; stored rotation for placed double rotationDeg = 0.0; if (interactive) { - rotationDeg = sig.rotation; + rotationDeg = sig.rotationDeg; } else if (placedIndex != null) { - final placementList = ref.read(pdfProvider).placementsByPage[pageNumber]; + final placementList = + ref.read(documentRepositoryProvider).placementsByPage[pageNumber]; if (placementList != null && placedIndex! < placementList.length) { rotationDeg = placementList[placedIndex!].rotationDeg; } diff --git a/lib/ui/features/signature/widgets/signature_card.dart b/lib/ui/features/signature/widgets/signature_card.dart index 6962b5b..23597a5 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/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import 'signature_drag_data.dart'; import 'rotated_signature_image.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; diff --git a/lib/ui/features/signature/widgets/signature_drag_data.dart b/lib/ui/features/signature/widgets/signature_drag_data.dart index f3b1eca..c21acbb 100644 --- a/lib/ui/features/signature/widgets/signature_drag_data.dart +++ b/lib/ui/features/signature/widgets/signature_drag_data.dart @@ -1,4 +1,4 @@ -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; class SignatureDragData { final SignatureAsset? asset; // null means use current processed signature diff --git a/lib/ui/features/welcome/widgets/welcome_screen.dart b/lib/ui/features/welcome/widgets/welcome_screen.dart index 0da17c4..a6fc4a0 100644 --- a/lib/ui/features/welcome/widgets/welcome_screen.dart +++ b/lib/ui/features/welcome/widgets/welcome_screen.dart @@ -50,7 +50,9 @@ Future handleDroppedFiles( bytes = null; } final String path = pdf.path ?? pdf.name; - read(pdfProvider.notifier).openPicked(path: path, bytes: bytes); + read( + documentRepositoryProvider.notifier, + ).openPicked(path: path, bytes: bytes); read(signatureProvider.notifier).resetForNewPage(); } @@ -74,7 +76,9 @@ class _WelcomeScreenState extends ConsumerState { } catch (_) { bytes = null; } - ref.read(pdfProvider.notifier).openPicked(path: file.path, bytes: bytes); + ref + .read(documentRepositoryProvider.notifier) + .openPicked(path: file.path, bytes: bytes); ref.read(signatureProvider.notifier).resetForNewPage(); } } diff --git a/pubspec.yaml b/pubspec.yaml index af6a439..efc6edb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -52,6 +52,11 @@ dependencies: flutter_localized_locales: ^2.0.5 desktop_drop: ^0.5.0 multi_split_view: ^3.6.1 + freezed_annotation: ^3.1.0 + json_annotation: ^4.9.0 + share_plus: ^11.1.0 + logging: ^1.3.0 + riverpod_annotation: ^2.6.1 dev_dependencies: flutter_test: @@ -61,6 +66,8 @@ dev_dependencies: build_runner: ^2.4.12 build: ^3.0.2 bdd_widget_test: ^2.0.1 + mocktail: ^1.0.4 + freezed: ^3.0.0 custom_lint: ^0.7.6 riverpod_lint: ^2.6.5 diff --git a/test/features/step/a_created_signature_card.dart b/test/features/step/a_created_signature_card.dart index bde5f49..0057b6e 100644 --- a/test/features/step/a_created_signature_card.dart +++ b/test/features/step/a_created_signature_card.dart @@ -1,8 +1,8 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a created signature card @@ -15,5 +15,5 @@ Future aCreatedSignatureCard(WidgetTester tester) async { bytes: Uint8List(100), name: 'Test Card', ); - container.read(signatureLibraryProvider.notifier).state = [asset]; + container.read(signatureAssetRepositoryProvider.notifier).state = [asset]; } diff --git a/test/features/step/a_document_is_open_and_contains_at_least_one_signature_placement.dart b/test/features/step/a_document_is_open_and_contains_at_least_one_signature_placement.dart index ab8d2d8..1170cc9 100644 --- a/test/features/step/a_document_is_open_and_contains_at_least_one_signature_placement.dart +++ b/test/features/step/a_document_is_open_and_contains_at_least_one_signature_placement.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a document is open and contains at least one signature placement @@ -13,10 +13,10 @@ Future aDocumentIsOpenAndContainsAtLeastOneSignaturePlacement( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'test.pdf', pageCount: 5); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 1, rect: Rect.fromLTWH(10, 10, 100, 50), diff --git a/test/features/step/a_document_is_open_and_contains_multiple_placed_signature_placements_across_pages.dart b/test/features/step/a_document_is_open_and_contains_multiple_placed_signature_placements_across_pages.dart index e1342f7..e11c368 100644 --- a/test/features/step/a_document_is_open_and_contains_multiple_placed_signature_placements_across_pages.dart +++ b/test/features/step/a_document_is_open_and_contains_multiple_placed_signature_placements_across_pages.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a document is open and contains multiple placed signature placements across pages @@ -14,24 +14,24 @@ aDocumentIsOpenAndContainsMultiplePlacedSignaturePlacementsAcrossPages( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'multi.pdf', pageCount: 5); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 1, rect: Rect.fromLTWH(10, 10, 100, 50), asset: SignatureAsset(id: 'sig1.png', bytes: Uint8List(0)), ); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 2, rect: Rect.fromLTWH(20, 20, 100, 50), asset: SignatureAsset(id: 'sig2.png', bytes: Uint8List(0)), ); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 3, rect: Rect.fromLTWH(30, 30, 100, 50), diff --git a/test/features/step/a_document_is_open_with_no_signature_placements_placed.dart b/test/features/step/a_document_is_open_with_no_signature_placements_placed.dart index ad9f196..fab4a0c 100644 --- a/test/features/step/a_document_is_open_with_no_signature_placements_placed.dart +++ b/test/features/step/a_document_is_open_with_no_signature_placements_placed.dart @@ -10,7 +10,7 @@ Future aDocumentIsOpenWithNoSignaturePlacementsPlaced( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'empty.pdf', pageCount: 5); // No placements added } diff --git a/test/features/step/a_document_page_is_selected_for_signing.dart b/test/features/step/a_document_page_is_selected_for_signing.dart index 88f257b..79f88e4 100644 --- a/test/features/step/a_document_page_is_selected_for_signing.dart +++ b/test/features/step/a_document_page_is_selected_for_signing.dart @@ -7,6 +7,6 @@ import '_world.dart'; Future aDocumentPageIsSelectedForSigning(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - container.read(pdfProvider.notifier).setSignedPage(1); - container.read(pdfProvider.notifier).jumpTo(1); + container.read(documentRepositoryProvider.notifier).setSignedPage(1); + container.read(documentRepositoryProvider.notifier).jumpTo(1); } diff --git a/test/features/step/a_multipage_document_is_open.dart b/test/features/step/a_multipage_document_is_open.dart index d7451c8..a299b37 100644 --- a/test/features/step/a_multipage_document_is_open.dart +++ b/test/features/step/a_multipage_document_is_open.dart @@ -2,18 +2,23 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a multi-page document is open Future aMultipageDocumentIsOpen(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - container.read(signatureLibraryProvider.notifier).state = []; - container.read(pdfProvider.notifier).state = PdfState.initial(); - container.read(signatureProvider.notifier).state = SignatureState.initial(); + container.read(signatureAssetRepositoryProvider.notifier).state = []; + container.read(documentRepositoryProvider.notifier).state = + Document.initial(); + container.read(signatureCardProvider.notifier).state = + SignatureCard.initial(); + container.read(currentRectProvider.notifier).state = null; + container.read(editingEnabledProvider.notifier).state = false; + container.read(aspectLockedProvider.notifier).state = false; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 5); } diff --git a/test/features/step/a_sample_multipage_document5_pages_is_available.dart b/test/features/step/a_sample_multipage_document5_pages_is_available.dart index 219627f..2054d67 100644 --- a/test/features/step/a_sample_multipage_document5_pages_is_available.dart +++ b/test/features/step/a_sample_multipage_document5_pages_is_available.dart @@ -10,6 +10,6 @@ Future aSampleMultipageDocument5PagesIsAvailable( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'sample.pdf', pageCount: 5); } diff --git a/test/features/step/a_signature_asset_is_created.dart b/test/features/step/a_signature_asset_is_created.dart index 779d7ca..156c654 100644 --- a/test/features/step/a_signature_asset_is_created.dart +++ b/test/features/step/a_signature_asset_is_created.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature asset is created @@ -13,9 +13,9 @@ Future aSignatureAssetIsCreated(WidgetTester tester) async { TestWorld.container = container; // Ensure PDF is open - if (!container.read(pdfProvider).loaded) { + if (!container.read(documentRepositoryProvider).loaded) { container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 5); } @@ -25,12 +25,12 @@ Future aSignatureAssetIsCreated(WidgetTester tester) async { bytes: Uint8List(100), name: 'Test Asset', ); - container.read(signatureLibraryProvider.notifier).state = [asset]; + container.read(signatureAssetRepositoryProvider.notifier).state = [asset]; // Place it on the current page - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: pdf.currentPage, rect: Rect.fromLTWH(50, 50, 100, 50), diff --git a/test/features/step/a_signature_asset_is_loaded_or_drawn.dart b/test/features/step/a_signature_asset_is_loaded_or_drawn.dart index 54d8617..73b6974 100644 --- a/test/features/step/a_signature_asset_is_loaded_or_drawn.dart +++ b/test/features/step/a_signature_asset_is_loaded_or_drawn.dart @@ -1,21 +1,26 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature asset is loaded or drawn Future aSignatureAssetIsLoadedOrDrawn(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - container.read(signatureLibraryProvider.notifier).state = []; - container.read(pdfProvider.notifier).state = PdfState.initial(); - container.read(signatureProvider.notifier).state = SignatureState.initial(); + container.read(signatureAssetRepositoryProvider.notifier).state = []; + container.read(documentRepositoryProvider.notifier).state = + Document.initial(); + container.read(signatureCardProvider.notifier).state = + SignatureCard.initial(); + container.read(currentRectProvider.notifier).state = null; + container.read(editingEnabledProvider.notifier).state = false; + container.read(aspectLockedProvider.notifier).state = false; final bytes = Uint8List.fromList([1, 2, 3, 4, 5]); container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(bytes, name: 'test.png'); } diff --git a/test/features/step/a_signature_asset_is_placed_on_the_page.dart b/test/features/step/a_signature_asset_is_placed_on_the_page.dart index b51458c..6fd7e6f 100644 --- a/test/features/step/a_signature_asset_is_placed_on_the_page.dart +++ b/test/features/step/a_signature_asset_is_placed_on_the_page.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature asset is placed on the page @@ -13,31 +13,31 @@ Future aSignatureAssetIsPlacedOnThePage(WidgetTester tester) async { TestWorld.container = container; // Ensure PDF is open - if (!container.read(pdfProvider).loaded) { + if (!container.read(documentRepositoryProvider).loaded) { container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 5); } // Get or create an asset - var library = container.read(signatureLibraryProvider); + var library = container.read(signatureAssetRepositoryProvider); SignatureAsset asset; if (library.isNotEmpty) { asset = library.first; } else { final bytes = Uint8List.fromList([1, 2, 3, 4, 5]); final id = container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(bytes, name: 'test.png'); asset = container - .read(signatureLibraryProvider) + .read(signatureAssetRepositoryProvider) .firstWhere((a) => a.id == id); } // Place it on the current page - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: pdf.currentPage, rect: Rect.fromLTWH(50, 50, 100, 50), diff --git a/test/features/step/a_signature_asset_is_selected.dart b/test/features/step/a_signature_asset_is_selected.dart index 2806cf2..f8c8523 100644 --- a/test/features/step/a_signature_asset_is_selected.dart +++ b/test/features/step/a_signature_asset_is_selected.dart @@ -1,15 +1,15 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature asset is selected Future aSignatureAssetIsSelected(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - var library = container.read(signatureLibraryProvider); + var library = container.read(signatureAssetRepositoryProvider); // If library is empty, add a dummy asset if (library.isEmpty) { @@ -18,9 +18,9 @@ Future aSignatureAssetIsSelected(WidgetTester tester) async { bytes: Uint8List(100), name: 'Selected Asset', ); - container.read(signatureLibraryProvider.notifier).state = [asset]; + container.read(signatureAssetRepositoryProvider.notifier).state = [asset]; // Re-read the library - library = container.read(signatureLibraryProvider); + library = container.read(signatureAssetRepositoryProvider); } expect( diff --git a/test/features/step/a_signature_asset_loaded_or_drawn_is_wrapped_in_a_signature_card.dart b/test/features/step/a_signature_asset_loaded_or_drawn_is_wrapped_in_a_signature_card.dart index 1432152..8f416d1 100644 --- a/test/features/step/a_signature_asset_loaded_or_drawn_is_wrapped_in_a_signature_card.dart +++ b/test/features/step/a_signature_asset_loaded_or_drawn_is_wrapped_in_a_signature_card.dart @@ -1,10 +1,10 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature asset loaded or drawn is wrapped in a signature card @@ -13,11 +13,16 @@ Future aSignatureAssetLoadedOrDrawnIsWrappedInASignatureCard( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - container.read(signatureLibraryProvider.notifier).state = []; - container.read(pdfProvider.notifier).state = PdfState.initial(); - container.read(signatureProvider.notifier).state = SignatureState.initial(); + container.read(signatureAssetRepositoryProvider.notifier).state = []; + container.read(documentRepositoryProvider.notifier).state = + Document.initial(); + container.read(signatureCardProvider.notifier).state = + SignatureCard.initial(); + container.read(currentRectProvider.notifier).state = null; + container.read(editingEnabledProvider.notifier).state = false; + container.read(aspectLockedProvider.notifier).state = false; final bytes = Uint8List.fromList([1, 2, 3, 4, 5]); container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(bytes, name: 'test.png'); } diff --git a/test/features/step/a_signature_placement_appears_on_the_page_based_on_the_signature_card.dart b/test/features/step/a_signature_placement_appears_on_the_page_based_on_the_signature_card.dart index edce35a..40433a2 100644 --- a/test/features/step/a_signature_placement_appears_on_the_page_based_on_the_signature_card.dart +++ b/test/features/step/a_signature_placement_appears_on_the_page_based_on_the_signature_card.dart @@ -7,7 +7,7 @@ Future aSignaturePlacementAppearsOnThePageBasedOnTheSignatureCard( WidgetTester tester, ) async { final container = TestWorld.container!; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final placements = pdf.placementsByPage[pdf.currentPage] ?? []; expect( placements.isNotEmpty, diff --git a/test/features/step/a_signature_placement_is_placed_on_page.dart b/test/features/step/a_signature_placement_is_placed_on_page.dart index c5ccad9..fb9809b 100644 --- a/test/features/step/a_signature_placement_is_placed_on_page.dart +++ b/test/features/step/a_signature_placement_is_placed_on_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature placement is placed on page {2} @@ -15,7 +15,7 @@ Future aSignaturePlacementIsPlacedOnPage( TestWorld.container = container; final page = param1.toInt(); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: page, rect: Rect.fromLTWH(20, 20, 100, 50), diff --git a/test/features/step/a_signature_placement_is_placed_with_a_position_and_size_relative_to_the_page.dart b/test/features/step/a_signature_placement_is_placed_with_a_position_and_size_relative_to_the_page.dart index 0c7126c..5cadc26 100644 --- a/test/features/step/a_signature_placement_is_placed_with_a_position_and_size_relative_to_the_page.dart +++ b/test/features/step/a_signature_placement_is_placed_with_a_position_and_size_relative_to_the_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: a signature placement is placed with a position and size relative to the page @@ -12,9 +12,9 @@ Future aSignaturePlacementIsPlacedWithAPositionAndSizeRelativeToThePage( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: pdf.currentPage, rect: Rect.fromLTWH(50, 50, 200, 100), diff --git a/test/features/step/adjusting_one_instance_does_not_affect_the_others.dart b/test/features/step/adjusting_one_instance_does_not_affect_the_others.dart index df373ee..33c0d14 100644 --- a/test/features/step/adjusting_one_instance_does_not_affect_the_others.dart +++ b/test/features/step/adjusting_one_instance_does_not_affect_the_others.dart @@ -1,7 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: adjusting one instance does not affect the others @@ -9,13 +9,19 @@ Future adjustingOneInstanceDoesNotAffectTheOthers( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final before = container.read(pdfProvider.notifier).placementsOn(2); + final before = container + .read(documentRepositoryProvider.notifier) + .placementsOn(2); expect(before.length, greaterThanOrEqualTo(2)); final modified = before[0].rect.translate(5, 0).inflate(3); - container.read(pdfProvider.notifier).removePlacement(page: 2, index: 0); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) + .removePlacement(page: 2, index: 0); + container + .read(documentRepositoryProvider.notifier) .addPlacement(page: 2, rect: modified, asset: before[0].asset); - final after = container.read(pdfProvider.notifier).placementsOn(2); + final after = container + .read(documentRepositoryProvider.notifier) + .placementsOn(2); expect(after.any((p) => p.rect == before[1].rect), isTrue); } diff --git a/test/features/step/adjusting_one_of_the_signature_placements_does_not_affect_the_others.dart b/test/features/step/adjusting_one_of_the_signature_placements_does_not_affect_the_others.dart index 1f7c3be..c7803f2 100644 --- a/test/features/step/adjusting_one_of_the_signature_placements_does_not_affect_the_others.dart +++ b/test/features/step/adjusting_one_of_the_signature_placements_does_not_affect_the_others.dart @@ -7,7 +7,7 @@ Future adjustingOneOfTheSignaturePlacementsDoesNotAffectTheOthers( WidgetTester tester, ) async { final container = TestWorld.container!; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final placements = pdf.placementsByPage.values.expand((list) => list).toList(); diff --git a/test/features/step/all_placed_signature_placements_appear_on_their_corresponding_pages_in_the_output.dart b/test/features/step/all_placed_signature_placements_appear_on_their_corresponding_pages_in_the_output.dart index 1d4f6f2..c4c203d 100644 --- a/test/features/step/all_placed_signature_placements_appear_on_their_corresponding_pages_in_the_output.dart +++ b/test/features/step/all_placed_signature_placements_appear_on_their_corresponding_pages_in_the_output.dart @@ -9,7 +9,7 @@ allPlacedSignaturePlacementsAppearOnTheirCorrespondingPagesInTheOutput( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final totalPlacements = pdf.placementsByPage.values.fold( 0, (sum, list) => sum + list.length, diff --git a/test/features/step/both_signature_placements_are_shown_on_their_respective_pages.dart b/test/features/step/both_signature_placements_are_shown_on_their_respective_pages.dart index 2c36541..0848794 100644 --- a/test/features/step/both_signature_placements_are_shown_on_their_respective_pages.dart +++ b/test/features/step/both_signature_placements_are_shown_on_their_respective_pages.dart @@ -8,7 +8,7 @@ Future bothSignaturePlacementsAreShownOnTheirRespectivePages( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); expect(pdf.placementsByPage[1], isNotEmpty); expect(pdf.placementsByPage[3], isNotEmpty); } diff --git a/test/features/step/dragging_or_resizing_one_does_not_change_the_other.dart b/test/features/step/dragging_or_resizing_one_does_not_change_the_other.dart index eb52f9a..de5623c 100644 --- a/test/features/step/dragging_or_resizing_one_does_not_change_the_other.dart +++ b/test/features/step/dragging_or_resizing_one_does_not_change_the_other.dart @@ -2,7 +2,7 @@ import 'dart:ui'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: dragging or resizing one does not change the other @@ -10,20 +10,26 @@ Future draggingOrResizingOneDoesNotChangeTheOther( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final list = container.read(pdfProvider.notifier).placementsOn(1); + final list = container + .read(documentRepositoryProvider.notifier) + .placementsOn(1); expect(list.length, greaterThanOrEqualTo(2)); final before = List.from(list.take(2).map((p) => p.rect)); // Simulate changing the first only final changed = before[0].inflate(5); - container.read(pdfProvider.notifier).removePlacement(page: 1, index: 0); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) + .removePlacement(page: 1, index: 0); + container + .read(documentRepositoryProvider.notifier) .addPlacement( page: 1, rect: changed, asset: list[1].asset, rotationDeg: list[1].rotationDeg, ); - final after = container.read(pdfProvider.notifier).placementsOn(1); + final after = container + .read(documentRepositoryProvider.notifier) + .placementsOn(1); expect(after.any((p) => p.rect == before[1]), isTrue); } diff --git a/test/features/step/each_signature_placement_can_be_dragged_and_resized_independently.dart b/test/features/step/each_signature_placement_can_be_dragged_and_resized_independently.dart index d2197cd..c14b648 100644 --- a/test/features/step/each_signature_placement_can_be_dragged_and_resized_independently.dart +++ b/test/features/step/each_signature_placement_can_be_dragged_and_resized_independently.dart @@ -8,7 +8,7 @@ Future eachSignaturePlacementCanBeDraggedAndResizedIndependently( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final placements = pdf.placementsByPage[pdf.currentPage] ?? []; expect(placements.length, greaterThan(1)); } diff --git a/test/features/step/identical_signature_instances_appear_in_each_location.dart b/test/features/step/identical_signature_instances_appear_in_each_location.dart index 8c9e6e3..f38ac9b 100644 --- a/test/features/step/identical_signature_instances_appear_in_each_location.dart +++ b/test/features/step/identical_signature_instances_appear_in_each_location.dart @@ -9,7 +9,7 @@ Future identicalSignatureInstancesAppearInEachLocation( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final state = container.read(pdfProvider); + final state = container.read(documentRepositoryProvider); final p2 = state.placementsByPage[2] ?? const []; final p4 = state.placementsByPage[4] ?? const []; expect(p2.length, greaterThanOrEqualTo(2)); diff --git a/test/features/step/identical_signature_placements_appear_in_each_location.dart b/test/features/step/identical_signature_placements_appear_in_each_location.dart index 52068ae..02d18be 100644 --- a/test/features/step/identical_signature_placements_appear_in_each_location.dart +++ b/test/features/step/identical_signature_placements_appear_in_each_location.dart @@ -8,7 +8,7 @@ Future identicalSignaturePlacementsAppearInEachLocation( WidgetTester tester, ) async { final container = TestWorld.container!; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final allPlacements = pdf.placementsByPage.values.expand((list) => list).toList(); final assetIds = allPlacements.map((p) => p.asset.id).toSet(); diff --git a/test/features/step/only_the_selected_signature_placement_is_removed.dart b/test/features/step/only_the_selected_signature_placement_is_removed.dart index 1d2e8fe..6078012 100644 --- a/test/features/step/only_the_selected_signature_placement_is_removed.dart +++ b/test/features/step/only_the_selected_signature_placement_is_removed.dart @@ -8,7 +8,7 @@ Future onlyTheSelectedSignaturePlacementIsRemoved( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final placements = pdf.placementsByPage[pdf.currentPage] ?? []; expect(placements.length, 2); // Started with 3, removed 1, should have 2 } diff --git a/test/features/step/page_becomes_visible_in_the_scroll_area.dart b/test/features/step/page_becomes_visible_in_the_scroll_area.dart index 25bcbfa..3baaea6 100644 --- a/test/features/step/page_becomes_visible_in_the_scroll_area.dart +++ b/test/features/step/page_becomes_visible_in_the_scroll_area.dart @@ -10,5 +10,5 @@ Future pageBecomesVisibleInTheScrollArea( ) async { final page = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - expect(c.read(pdfProvider).currentPage, page); + expect(c.read(documentRepositoryProvider).currentPage, page); } diff --git a/test/features/step/page_is_displayed.dart b/test/features/step/page_is_displayed.dart index 5591083..c5b8a56 100644 --- a/test/features/step/page_is_displayed.dart +++ b/test/features/step/page_is_displayed.dart @@ -7,5 +7,5 @@ import '_world.dart'; Future pageIsDisplayed(WidgetTester tester, num param1) async { final expected = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - expect(c.read(pdfProvider).currentPage, expected); + expect(c.read(documentRepositoryProvider).currentPage, expected); } diff --git a/test/features/step/resize_to_fit_within_bounding_box.dart b/test/features/step/resize_to_fit_within_bounding_box.dart index f2c6c35..f0d8ce8 100644 --- a/test/features/step/resize_to_fit_within_bounding_box.dart +++ b/test/features/step/resize_to_fit_within_bounding_box.dart @@ -6,7 +6,7 @@ import '_world.dart'; /// Usage: resize to fit within bounding box Future resizeToFitWithinBoundingBox(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); if (pdf.selectedPlacementIndex != null) { final placements = pdf.placementsByPage[pdf.currentPage] ?? []; diff --git a/test/features/step/signature_placement_occurs_on_the_selected_page.dart b/test/features/step/signature_placement_occurs_on_the_selected_page.dart index 0af29f8..2238cd3 100644 --- a/test/features/step/signature_placement_occurs_on_the_selected_page.dart +++ b/test/features/step/signature_placement_occurs_on_the_selected_page.dart @@ -9,7 +9,7 @@ Future signaturePlacementOccursOnTheSelectedPage( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); // Check that there's at least one placement on the current page final placements = pdf.placementsByPage[pdf.currentPage] ?? []; diff --git a/test/features/step/the_app_attempts_to_load_the_asset.dart b/test/features/step/the_app_attempts_to_load_the_asset.dart index 66c1f24..0864450 100644 --- a/test/features/step/the_app_attempts_to_load_the_asset.dart +++ b/test/features/step/the_app_attempts_to_load_the_asset.dart @@ -1,6 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; /// Usage: the app attempts to load the asset @@ -8,6 +8,6 @@ Future theAppAttemptsToLoadTheAsset(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; // Simulate attempting to load an asset - for now just ensure library is accessible - final library = container.read(signatureLibraryProvider); + final library = container.read(signatureAssetRepositoryProvider); expect(library, isNotNull); } diff --git a/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_asset.dart b/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_asset.dart index c096f35..b2001a8 100644 --- a/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_asset.dart +++ b/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_asset.dart @@ -1,5 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; /// Usage: the asset is loaded and shown as a signature asset @@ -7,7 +7,7 @@ Future theAssetIsLoadedAndShownAsASignatureAsset( WidgetTester tester, ) async { final container = TestWorld.container!; - final library = container.read(signatureLibraryProvider); + final library = container.read(signatureAssetRepositoryProvider); expect( library.isNotEmpty, true, diff --git a/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_card.dart b/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_card.dart index ca8f107..9b7fa1b 100644 --- a/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_card.dart +++ b/test/features/step/the_asset_is_loaded_and_shown_as_a_signature_card.dart @@ -1,5 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; /// Usage: the asset is loaded and shown as a signature card @@ -7,7 +7,7 @@ Future theAssetIsLoadedAndShownAsASignatureCard( WidgetTester tester, ) async { final container = TestWorld.container!; - final library = container.read(signatureLibraryProvider); + final library = container.read(signatureAssetRepositoryProvider); expect( library.isNotEmpty, true, diff --git a/test/features/step/the_asset_is_not_added_to_the_document.dart b/test/features/step/the_asset_is_not_added_to_the_document.dart index 76c835f..d7b659f 100644 --- a/test/features/step/the_asset_is_not_added_to_the_document.dart +++ b/test/features/step/the_asset_is_not_added_to_the_document.dart @@ -1,11 +1,11 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; /// Usage: the asset is not added to the document Future theAssetIsNotAddedToTheDocument(WidgetTester tester) async { final container = TestWorld.container!; - final library = container.read(signatureLibraryProvider); + final library = container.read(signatureAssetRepositoryProvider); expect( library.isEmpty, true, diff --git a/test/features/step/the_document_is_open.dart b/test/features/step/the_document_is_open.dart index a4f7bcd..f59d389 100644 --- a/test/features/step/the_document_is_open.dart +++ b/test/features/step/the_document_is_open.dart @@ -7,7 +7,7 @@ import '_world.dart'; Future theDocumentIsOpen(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); expect(pdf.loaded, isTrue); expect(pdf.pageCount, greaterThan(0)); } diff --git a/test/features/step/the_first_page_is_displayed.dart b/test/features/step/the_first_page_is_displayed.dart index 07e2de2..01e2f89 100644 --- a/test/features/step/the_first_page_is_displayed.dart +++ b/test/features/step/the_first_page_is_displayed.dart @@ -6,6 +6,6 @@ import '_world.dart'; /// Usage: the first page is displayed Future theFirstPageIsDisplayed(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); expect(pdf.currentPage, 1); } diff --git a/test/features/step/the_go_to_input_cannot_be_used.dart b/test/features/step/the_go_to_input_cannot_be_used.dart index fac6f98..7e8e936 100644 --- a/test/features/step/the_go_to_input_cannot_be_used.dart +++ b/test/features/step/the_go_to_input_cannot_be_used.dart @@ -7,9 +7,9 @@ import '_world.dart'; Future theGoToInputCannotBeUsed(WidgetTester tester) async { final c = TestWorld.container ?? ProviderContainer(); // Not loaded, currentPage should remain 1 even after jump attempt - expect(c.read(pdfProvider).loaded, isFalse); - final before = c.read(pdfProvider).currentPage; - c.read(pdfProvider.notifier).jumpTo(3); - final after = c.read(pdfProvider).currentPage; + expect(c.read(documentRepositoryProvider).loaded, isFalse); + final before = c.read(documentRepositoryProvider).currentPage; + c.read(documentRepositoryProvider.notifier).jumpTo(3); + final after = c.read(documentRepositoryProvider).currentPage; expect(before, equals(after)); } diff --git a/test/features/step/the_last_page_is_displayed_page.dart b/test/features/step/the_last_page_is_displayed_page.dart index 3557987..5efb379 100644 --- a/test/features/step/the_last_page_is_displayed_page.dart +++ b/test/features/step/the_last_page_is_displayed_page.dart @@ -7,7 +7,7 @@ import '_world.dart'; Future theLastPageIsDisplayedPage(WidgetTester tester, num param1) async { final last = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - final pdf = c.read(pdfProvider); + final pdf = c.read(documentRepositoryProvider); expect(pdf.pageCount, last); expect(pdf.currentPage, last); } diff --git a/test/features/step/the_left_pages_overview_highlights_page.dart b/test/features/step/the_left_pages_overview_highlights_page.dart index 48f0b46..ce46890 100644 --- a/test/features/step/the_left_pages_overview_highlights_page.dart +++ b/test/features/step/the_left_pages_overview_highlights_page.dart @@ -10,5 +10,5 @@ Future theLeftPagesOverviewHighlightsPage( ) async { final n = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - expect(c.read(pdfProvider).currentPage, n); + expect(c.read(documentRepositoryProvider).currentPage, n); } diff --git a/test/features/step/the_other_signature_placements_remain_unchanged.dart b/test/features/step/the_other_signature_placements_remain_unchanged.dart index 5a19111..123f40f 100644 --- a/test/features/step/the_other_signature_placements_remain_unchanged.dart +++ b/test/features/step/the_other_signature_placements_remain_unchanged.dart @@ -7,7 +7,7 @@ Future theOtherSignaturePlacementsRemainUnchanged( WidgetTester tester, ) async { final container = TestWorld.container!; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final placements = pdf.placementsByPage[pdf.currentPage] ?? []; expect(placements.length, 2); // Should have 2 remaining after deleting 1 } diff --git a/test/features/step/the_page_label_shows_page_of.dart b/test/features/step/the_page_label_shows_page_of.dart index e6bcb9d..79b9643 100644 --- a/test/features/step/the_page_label_shows_page_of.dart +++ b/test/features/step/the_page_label_shows_page_of.dart @@ -12,7 +12,7 @@ Future thePageLabelShowsPageOf( final current = param1.toInt(); final total = param2.toInt(); final c = TestWorld.container ?? ProviderContainer(); - final pdf = c.read(pdfProvider); + final pdf = c.read(documentRepositoryProvider); expect(pdf.currentPage, current); expect(pdf.pageCount, total); } diff --git a/test/features/step/the_signature_placement_is_stamped_at_the_exact_pdf_page_coordinates_and_size.dart b/test/features/step/the_signature_placement_is_stamped_at_the_exact_pdf_page_coordinates_and_size.dart index 0eb2634..8264ea5 100644 --- a/test/features/step/the_signature_placement_is_stamped_at_the_exact_pdf_page_coordinates_and_size.dart +++ b/test/features/step/the_signature_placement_is_stamped_at_the_exact_pdf_page_coordinates_and_size.dart @@ -10,7 +10,7 @@ Future theSignaturePlacementIsStampedAtTheExactPdfPageCoordinatesAndSize( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdfState = container.read(pdfProvider); + final pdfState = container.read(documentRepositoryProvider); // Verify PDF is loaded expect(pdfState.loaded, isTrue, reason: 'PDF should be loaded'); diff --git a/test/features/step/the_signature_placement_on_page_is_shown_on_page.dart b/test/features/step/the_signature_placement_on_page_is_shown_on_page.dart index 0c91f51..a094c29 100644 --- a/test/features/step/the_signature_placement_on_page_is_shown_on_page.dart +++ b/test/features/step/the_signature_placement_on_page_is_shown_on_page.dart @@ -10,7 +10,7 @@ Future theSignaturePlacementOnPageIsShownOnPage( num param2, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final page = param1.toInt(); expect(pdf.placementsByPage[page], isNotEmpty); } diff --git a/test/features/step/the_signature_placement_on_page_remains.dart b/test/features/step/the_signature_placement_on_page_remains.dart index dd6e199..7f24950 100644 --- a/test/features/step/the_signature_placement_on_page_remains.dart +++ b/test/features/step/the_signature_placement_on_page_remains.dart @@ -9,7 +9,7 @@ Future theSignaturePlacementOnPageRemains( num param1, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final page = param1.toInt(); expect(pdf.placementsByPage[page], isNotEmpty); } diff --git a/test/features/step/the_signature_placement_remains_within_the_page_area.dart b/test/features/step/the_signature_placement_remains_within_the_page_area.dart index cafed7c..29eeb53 100644 --- a/test/features/step/the_signature_placement_remains_within_the_page_area.dart +++ b/test/features/step/the_signature_placement_remains_within_the_page_area.dart @@ -8,7 +8,7 @@ Future theSignaturePlacementRemainsWithinThePageArea( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final placements = pdf.placementsByPage[pdf.currentPage] ?? []; for (final placement in placements) { diff --git a/test/features/step/the_signature_placement_rotates_around_its_center_in_real_time.dart b/test/features/step/the_signature_placement_rotates_around_its_center_in_real_time.dart index 0b2391a..1815877 100644 --- a/test/features/step/the_signature_placement_rotates_around_its_center_in_real_time.dart +++ b/test/features/step/the_signature_placement_rotates_around_its_center_in_real_time.dart @@ -8,7 +8,7 @@ Future theSignaturePlacementRotatesAroundItsCenterInRealTime( WidgetTester tester, ) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); if (pdf.selectedPlacementIndex != null) { final placements = pdf.placementsByPage[pdf.currentPage] ?? []; diff --git a/test/features/step/the_signature_placements_appear_on_the_corresponding_page_in_the_output.dart b/test/features/step/the_signature_placements_appear_on_the_corresponding_page_in_the_output.dart index e3cd09a..0b44b47 100644 --- a/test/features/step/the_signature_placements_appear_on_the_corresponding_page_in_the_output.dart +++ b/test/features/step/the_signature_placements_appear_on_the_corresponding_page_in_the_output.dart @@ -10,7 +10,7 @@ Future theSignaturePlacementsAppearOnTheCorrespondingPageInTheOutput( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdfState = container.read(pdfProvider); + final pdfState = container.read(documentRepositoryProvider); // Verify that export was successful expect( diff --git a/test/features/step/the_size_and_position_update_in_real_time.dart b/test/features/step/the_size_and_position_update_in_real_time.dart index 273e124..37bf23d 100644 --- a/test/features/step/the_size_and_position_update_in_real_time.dart +++ b/test/features/step/the_size_and_position_update_in_real_time.dart @@ -6,7 +6,7 @@ import '_world.dart'; /// Usage: the size and position update in real time Future theSizeAndPositionUpdateInRealTime(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); if (pdf.selectedPlacementIndex != null) { final placements = pdf.placementsByPage[pdf.currentPage] ?? []; diff --git a/test/features/step/the_user_attempts_to_save.dart b/test/features/step/the_user_attempts_to_save.dart index 955ab74..32e6990 100644 --- a/test/features/step/the_user_attempts_to_save.dart +++ b/test/features/step/the_user_attempts_to_save.dart @@ -8,7 +8,7 @@ import '_world.dart'; Future theUserAttemptsToSave(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final sig = container.read(signatureProvider); // Simulate save attempt: since rect is null, mark flag if (!pdf.loaded || sig.rect == null) { diff --git a/test/features/step/the_user_can_move_to_the_next_or_previous_page.dart b/test/features/step/the_user_can_move_to_the_next_or_previous_page.dart index 06cdd2e..0193f62 100644 --- a/test/features/step/the_user_can_move_to_the_next_or_previous_page.dart +++ b/test/features/step/the_user_can_move_to_the_next_or_previous_page.dart @@ -6,11 +6,11 @@ import '_world.dart'; /// Usage: the user can move to the next or previous page Future theUserCanMoveToTheNextOrPreviousPage(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); - final pdfN = container.read(pdfProvider.notifier); - final pdf = container.read(pdfProvider); + final pdfN = container.read(documentRepositoryProvider.notifier); + final pdf = container.read(documentRepositoryProvider); expect(pdf.currentPage, 1); pdfN.jumpTo(2); - expect(container.read(pdfProvider).currentPage, 2); + expect(container.read(documentRepositoryProvider).currentPage, 2); pdfN.jumpTo(1); - expect(container.read(pdfProvider).currentPage, 1); + expect(container.read(documentRepositoryProvider).currentPage, 1); } diff --git a/test/features/step/the_user_chooses_a_image_file_as_a_signature_asset.dart b/test/features/step/the_user_chooses_a_image_file_as_a_signature_asset.dart index 51f51a8..8479745 100644 --- a/test/features/step/the_user_chooses_a_image_file_as_a_signature_asset.dart +++ b/test/features/step/the_user_chooses_a_image_file_as_a_signature_asset.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; /// Usage: the user chooses a image file as a signature asset @@ -12,6 +12,6 @@ Future theUserChoosesAImageFileAsASignatureAsset( TestWorld.container = container; final bytes = Uint8List.fromList([1, 2, 3, 4, 5]); container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(bytes, name: 'chosen.png'); } diff --git a/test/features/step/the_user_chooses_a_signature_asset_to_created_a_signature_card.dart b/test/features/step/the_user_chooses_a_signature_asset_to_created_a_signature_card.dart index 91cbc46..e210913 100644 --- a/test/features/step/the_user_chooses_a_signature_asset_to_created_a_signature_card.dart +++ b/test/features/step/the_user_chooses_a_signature_asset_to_created_a_signature_card.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import '_world.dart'; /// Usage: the user chooses a signature asset to created a signature card @@ -12,6 +12,6 @@ Future theUserChoosesASignatureAssetToCreatedASignatureCard( TestWorld.container = container; final bytes = Uint8List.fromList([1, 2, 3, 4, 5]); container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(bytes, name: 'card.png'); } diff --git a/test/features/step/the_user_clicks_the_go_to_apply_button.dart b/test/features/step/the_user_clicks_the_go_to_apply_button.dart index 66b4731..5710c64 100644 --- a/test/features/step/the_user_clicks_the_go_to_apply_button.dart +++ b/test/features/step/the_user_clicks_the_go_to_apply_button.dart @@ -8,7 +8,7 @@ Future theUserClicksTheGoToApplyButton(WidgetTester tester) async { final c = TestWorld.container ?? ProviderContainer(); final pending = TestWorld.pendingGoTo; if (pending != null) { - c.read(pdfProvider.notifier).jumpTo(pending); + c.read(documentRepositoryProvider.notifier).jumpTo(pending); await tester.pump(); } } diff --git a/test/features/step/the_user_clicks_the_thumbnail_for_page.dart b/test/features/step/the_user_clicks_the_thumbnail_for_page.dart index b0cfb7c..d641a46 100644 --- a/test/features/step/the_user_clicks_the_thumbnail_for_page.dart +++ b/test/features/step/the_user_clicks_the_thumbnail_for_page.dart @@ -10,6 +10,6 @@ Future theUserClicksTheThumbnailForPage( ) async { final page = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - c.read(pdfProvider.notifier).jumpTo(page); + c.read(documentRepositoryProvider.notifier).jumpTo(page); await tester.pump(); } diff --git a/test/features/step/the_user_deletes_one_selected_signature_placement.dart b/test/features/step/the_user_deletes_one_selected_signature_placement.dart index e372581..5418460 100644 --- a/test/features/step/the_user_deletes_one_selected_signature_placement.dart +++ b/test/features/step/the_user_deletes_one_selected_signature_placement.dart @@ -9,9 +9,9 @@ Future theUserDeletesOneSelectedSignaturePlacement( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); if (pdf.selectedPlacementIndex == null) { - container.read(pdfProvider.notifier).selectPlacement(0); + container.read(documentRepositoryProvider.notifier).selectPlacement(0); } - container.read(pdfProvider.notifier).deleteSelectedPlacement(); + container.read(documentRepositoryProvider.notifier).deleteSelectedPlacement(); } diff --git a/test/features/step/the_user_drags_handles_to_resize_and_drags_to_reposition.dart b/test/features/step/the_user_drags_handles_to_resize_and_drags_to_reposition.dart index 0634c55..335572c 100644 --- a/test/features/step/the_user_drags_handles_to_resize_and_drags_to_reposition.dart +++ b/test/features/step/the_user_drags_handles_to_resize_and_drags_to_reposition.dart @@ -10,8 +10,8 @@ Future theUserDragsHandlesToResizeAndDragsToReposition( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); - final pdfN = container.read(pdfProvider.notifier); + final pdf = container.read(documentRepositoryProvider); + final pdfN = container.read(documentRepositoryProvider.notifier); if (pdf.selectedPlacementIndex != null) { final placements = pdf.placementsByPage[pdf.currentPage] ?? []; diff --git a/test/features/step/the_user_drags_it_on_the_page_of_the_document_to_place_signature_placements_in_multiple_locations_in_the_document.dart b/test/features/step/the_user_drags_it_on_the_page_of_the_document_to_place_signature_placements_in_multiple_locations_in_the_document.dart index e4e7502..465e4c2 100644 --- a/test/features/step/the_user_drags_it_on_the_page_of_the_document_to_place_signature_placements_in_multiple_locations_in_the_document.dart +++ b/test/features/step/the_user_drags_it_on_the_page_of_the_document_to_place_signature_placements_in_multiple_locations_in_the_document.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: the user drags it on the page of the document to place signature placements in multiple locations in the document @@ -13,7 +13,7 @@ theUserDragsItOnThePageOfTheDocumentToPlaceSignaturePlacementsInMultipleLocation WidgetTester tester, ) async { final container = TestWorld.container!; - final lib = container.read(signatureLibraryProvider); + final lib = container.read(signatureAssetRepositoryProvider); final asset = lib.isNotEmpty ? lib.first @@ -24,28 +24,28 @@ theUserDragsItOnThePageOfTheDocumentToPlaceSignaturePlacementsInMultipleLocation ); // Ensure PDF is open - if (!container.read(pdfProvider).loaded) { + if (!container.read(documentRepositoryProvider).loaded) { container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 5); } container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 1, rect: Rect.fromLTWH(10, 10, 100, 50), asset: asset, ); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 2, rect: Rect.fromLTWH(20, 20, 100, 50), asset: asset, ); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 3, rect: Rect.fromLTWH(30, 30, 100, 50), 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 0e99dc4..12452fe 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 @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: the user drags this signature card on the page of the document to place a signature placement @@ -16,31 +16,31 @@ theUserDragsThisSignatureCardOnThePageOfTheDocumentToPlaceASignaturePlacement( TestWorld.container = container; // Ensure PDF is open - if (!container.read(pdfProvider).loaded) { + if (!container.read(documentRepositoryProvider).loaded) { container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 5); } // Get or create an asset - var library = container.read(signatureLibraryProvider); + var library = container.read(signatureAssetRepositoryProvider); SignatureAsset asset; if (library.isNotEmpty) { asset = library.first; } else { final bytes = Uint8List.fromList([1, 2, 3, 4, 5]); final id = container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(bytes, name: 'placement.png'); asset = container - .read(signatureLibraryProvider) + .read(signatureAssetRepositoryProvider) .firstWhere((a) => a.id == id); } // Place it on the current page - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: pdf.currentPage, rect: Rect.fromLTWH(100, 100, 100, 50), diff --git a/test/features/step/the_user_enters_into_the_go_to_input_and_applies_it.dart b/test/features/step/the_user_enters_into_the_go_to_input_and_applies_it.dart index 8e5c01d..99590ab 100644 --- a/test/features/step/the_user_enters_into_the_go_to_input_and_applies_it.dart +++ b/test/features/step/the_user_enters_into_the_go_to_input_and_applies_it.dart @@ -10,6 +10,6 @@ Future theUserEntersIntoTheGoToInputAndAppliesIt( ) async { final value = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - c.read(pdfProvider.notifier).jumpTo(value); + c.read(documentRepositoryProvider.notifier).jumpTo(value); await tester.pump(); } diff --git a/test/features/step/the_user_jumps_to_page.dart b/test/features/step/the_user_jumps_to_page.dart index 888bbf9..440b952 100644 --- a/test/features/step/the_user_jumps_to_page.dart +++ b/test/features/step/the_user_jumps_to_page.dart @@ -7,6 +7,6 @@ import '_world.dart'; Future theUserJumpsToPage(WidgetTester tester, num param1) async { final page = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); - c.read(pdfProvider.notifier).jumpTo(page); + c.read(documentRepositoryProvider.notifier).jumpTo(page); await tester.pump(); } diff --git a/test/features/step/the_user_navigates_to_page_and_places_another_signature_placement.dart b/test/features/step/the_user_navigates_to_page_and_places_another_signature_placement.dart index be1da73..54841ac 100644 --- a/test/features/step/the_user_navigates_to_page_and_places_another_signature_placement.dart +++ b/test/features/step/the_user_navigates_to_page_and_places_another_signature_placement.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: the user navigates to page {5} and places another signature placement @@ -14,9 +14,9 @@ Future theUserNavigatesToPageAndPlacesAnotherSignaturePlacement( final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; final page = param1.toInt(); - container.read(pdfProvider.notifier).jumpTo(page); + container.read(documentRepositoryProvider.notifier).jumpTo(page); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: page, rect: Rect.fromLTWH(40, 40, 100, 50), 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 567d4ac..6e939aa 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 @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: the user places a signature placement from asset on page @@ -15,14 +15,14 @@ Future theUserPlacesASignaturePlacementFromAssetOnPage( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final library = container.read(signatureLibraryProvider); + final library = container.read(signatureAssetRepositoryProvider); var asset = library.where((a) => a.name == assetName).firstOrNull; if (asset == null) { // add dummy asset final id = container - .read(signatureLibraryProvider.notifier) + .read(signatureAssetRepositoryProvider.notifier) .add(Uint8List(0), name: assetName); - final updatedLibrary = container.read(signatureLibraryProvider); + final updatedLibrary = container.read(signatureAssetRepositoryProvider); asset = updatedLibrary.firstWhere( (a) => a.id == id, orElse: @@ -30,7 +30,7 @@ Future theUserPlacesASignaturePlacementFromAssetOnPage( ); } container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: page, rect: Rect.fromLTWH(10, 10, 50, 50), diff --git a/test/features/step/the_user_places_a_signature_placement_on_page.dart b/test/features/step/the_user_places_a_signature_placement_on_page.dart index dd043df..3d8419e 100644 --- a/test/features/step/the_user_places_a_signature_placement_on_page.dart +++ b/test/features/step/the_user_places_a_signature_placement_on_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: the user places a signature placement on page {1} @@ -15,7 +15,7 @@ Future theUserPlacesASignaturePlacementOnPage( TestWorld.container = container; final page = param1.toInt(); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: page, rect: Rect.fromLTWH(20, 20, 100, 50), diff --git a/test/features/step/the_user_places_it_in_multiple_locations_in_the_document.dart b/test/features/step/the_user_places_it_in_multiple_locations_in_the_document.dart index 18c028d..d2bb95f 100644 --- a/test/features/step/the_user_places_it_in_multiple_locations_in_the_document.dart +++ b/test/features/step/the_user_places_it_in_multiple_locations_in_the_document.dart @@ -10,7 +10,7 @@ Future theUserPlacesItInMultipleLocationsInTheDocument( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final notifier = container.read(pdfProvider.notifier); + final notifier = container.read(documentRepositoryProvider.notifier); // Always open a fresh doc to avoid state bleed between scenarios notifier.openPicked(path: 'mock.pdf', pageCount: 6); // Place two on page 2 and one on page 4 diff --git a/test/features/step/the_user_places_two_signature_placements_on_the_same_page.dart b/test/features/step/the_user_places_two_signature_placements_on_the_same_page.dart index 2905802..ce159bf 100644 --- a/test/features/step/the_user_places_two_signature_placements_on_the_same_page.dart +++ b/test/features/step/the_user_places_two_signature_placements_on_the_same_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: the user places two signature placements on the same page @@ -12,10 +12,10 @@ Future theUserPlacesTwoSignaturePlacementsOnTheSamePage( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final page = pdf.currentPage; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: page, rect: Rect.fromLTWH(10, 10, 100, 50), @@ -26,7 +26,7 @@ Future theUserPlacesTwoSignaturePlacementsOnTheSamePage( ), ); container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: page, rect: Rect.fromLTWH(120, 10, 100, 50), diff --git a/test/features/step/the_user_savesexports_the_document.dart b/test/features/step/the_user_savesexports_the_document.dart index f717666..9f4860b 100644 --- a/test/features/step/the_user_savesexports_the_document.dart +++ b/test/features/step/the_user_savesexports_the_document.dart @@ -12,7 +12,7 @@ Future theUserSavesexportsTheDocument(WidgetTester tester) async { TestWorld.container = container; // Ensure state looks exportable - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); final sig = container.read(signatureProvider); expect(pdf.loaded, isTrue, reason: 'PDF must be loaded before export'); // Check if there are placements diff --git a/test/features/step/the_user_selects.dart b/test/features/step/the_user_selects.dart index d2dfab2..307b5f9 100644 --- a/test/features/step/the_user_selects.dart +++ b/test/features/step/the_user_selects.dart @@ -11,9 +11,9 @@ Future theUserSelects(WidgetTester tester, dynamic file) async { TestWorld.container = container; // Mark page for signing to enable signature ops container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 1); - container.read(pdfProvider.notifier).setSignedPage(1); + container.read(documentRepositoryProvider.notifier).setSignedPage(1); // For invalid/unsupported/empty selections we do NOT set image bytes. // This simulates a failed load and keeps rect null. final token = file.toString(); diff --git a/test/features/step/the_user_types_into_the_go_to_input_and_presses_enter.dart b/test/features/step/the_user_types_into_the_go_to_input_and_presses_enter.dart index c80e1d7..d28dfd6 100644 --- a/test/features/step/the_user_types_into_the_go_to_input_and_presses_enter.dart +++ b/test/features/step/the_user_types_into_the_go_to_input_and_presses_enter.dart @@ -11,6 +11,6 @@ Future theUserTypesIntoTheGoToInputAndPressesEnter( final target = param1.toInt(); final c = TestWorld.container ?? ProviderContainer(); TestWorld.container = c; - c.read(pdfProvider.notifier).jumpTo(target); + c.read(documentRepositoryProvider.notifier).jumpTo(target); await tester.pump(); } diff --git a/test/features/step/the_user_uses_rotate_controls.dart b/test/features/step/the_user_uses_rotate_controls.dart index 74152de..a89be16 100644 --- a/test/features/step/the_user_uses_rotate_controls.dart +++ b/test/features/step/the_user_uses_rotate_controls.dart @@ -6,8 +6,8 @@ import '_world.dart'; /// Usage: the user uses rotate controls Future theUserUsesRotateControls(WidgetTester tester) async { final container = TestWorld.container ?? ProviderContainer(); - final pdf = container.read(pdfProvider); - final pdfN = container.read(pdfProvider.notifier); + final pdf = container.read(documentRepositoryProvider); + final pdfN = container.read(documentRepositoryProvider.notifier); if (pdf.selectedPlacementIndex != null) { // Rotate the selected placement by 45 degrees diff --git a/test/features/step/three_signature_placements_are_placed_on_the_current_page.dart b/test/features/step/three_signature_placements_are_placed_on_the_current_page.dart index 34d5034..e78ae27 100644 --- a/test/features/step/three_signature_placements_are_placed_on_the_current_page.dart +++ b/test/features/step/three_signature_placements_are_placed_on_the_current_page.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import '_world.dart'; /// Usage: three signature placements are placed on the current page @@ -14,14 +14,19 @@ Future threeSignaturePlacementsArePlacedOnTheCurrentPage( ) async { final container = TestWorld.container ?? ProviderContainer(); TestWorld.container = container; - container.read(signatureLibraryProvider.notifier).state = []; - container.read(pdfProvider.notifier).state = PdfState.initial(); - container.read(signatureProvider.notifier).state = SignatureState.initial(); + container.read(signatureAssetRepositoryProvider.notifier).state = []; + container.read(documentRepositoryProvider.notifier).state = + Document.initial(); + container.read(signatureCardProvider.notifier).state = + SignatureCard.initial(); + container.read(currentRectProvider.notifier).state = null; + container.read(editingEnabledProvider.notifier).state = false; + container.read(aspectLockedProvider.notifier).state = false; container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .openPicked(path: 'mock.pdf', pageCount: 5); - final pdfN = container.read(pdfProvider.notifier); - final pdf = container.read(pdfProvider); + final pdfN = container.read(documentRepositoryProvider.notifier); + final pdf = container.read(documentRepositoryProvider); final page = pdf.currentPage; pdfN.addPlacement( page: page, diff --git a/test/widget/export_flow_test.dart b/test/widget/export_flow_test.dart index 9327153..e71f258 100644 --- a/test/widget/export_flow_test.dart +++ b/test/widget/export_flow_test.dart @@ -26,8 +26,8 @@ void main() { await tester.pumpWidget( ProviderScope( overrides: [ - pdfProvider.overrideWith( - (ref) => PdfController()..openPicked(path: 'test.pdf'), + documentRepositoryProvider.overrideWith( + (ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'), ), signatureProvider.overrideWith( (ref) => SignatureController()..placeDefaultRect(), diff --git a/test/widget/helpers.dart b/test/widget/helpers.dart index 1d87832..7965322 100644 --- a/test/widget/helpers.dart +++ b/test/widget/helpers.dart @@ -15,8 +15,8 @@ Future pumpWithOpenPdf(WidgetTester tester) async { await tester.pumpWidget( ProviderScope( overrides: [ - pdfProvider.overrideWith( - (ref) => PdfController()..openPicked(path: 'test.pdf'), + documentRepositoryProvider.overrideWith( + (ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'), ), useMockViewerProvider.overrideWith((ref) => true), // Continuous mode is always-on; no page view override needed @@ -49,8 +49,8 @@ Future pumpWithOpenPdfAndSig(WidgetTester tester) async { await tester.pumpWidget( ProviderScope( overrides: [ - pdfProvider.overrideWith( - (ref) => PdfController()..openPicked(path: 'test.pdf'), + documentRepositoryProvider.overrideWith( + (ref) => DocumentStateNotifier()..openPicked(path: 'test.pdf'), ), signatureProvider.overrideWith( (ref) => diff --git a/test/widget/pdf_navigation_widget_test.dart b/test/widget/pdf_navigation_widget_test.dart index f686775..24c18de 100644 --- a/test/widget/pdf_navigation_widget_test.dart +++ b/test/widget/pdf_navigation_widget_test.dart @@ -4,14 +4,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/data/services/export_providers.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; -class _TestPdfController extends PdfController { +class _TestPdfController extends DocumentStateNotifier { _TestPdfController() : super() { // Start with a loaded multi-page doc, page 1 of 5 - state = PdfState.initial().copyWith( + state = Document.initial().copyWith( loaded: true, pageCount: 5, currentPage: 1, @@ -27,7 +27,9 @@ void main() { ProviderScope( overrides: [ useMockViewerProvider.overrideWithValue(true), - pdfProvider.overrideWith((ref) => _TestPdfController()), + documentRepositoryProvider.overrideWith( + (ref) => _TestPdfController(), + ), ], child: MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, diff --git a/test/widget/pdf_page_area_early_jump_test.dart b/test/widget/pdf_page_area_early_jump_test.dart index 06b7f9f..5e48ca3 100644 --- a/test/widget/pdf_page_area_early_jump_test.dart +++ b/test/widget/pdf_page_area_early_jump_test.dart @@ -6,11 +6,11 @@ import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/data/services/export_providers.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; -class _TestPdfController extends PdfController { +class _TestPdfController extends DocumentStateNotifier { _TestPdfController() : super() { - state = PdfState.initial().copyWith( + state = Document.initial().copyWith( loaded: true, pageCount: 6, currentPage: 1, @@ -30,7 +30,7 @@ void main() { overrides: [ useMockViewerProvider.overrideWithValue(true), // Continuous mode is always-on; no page view override needed - pdfProvider.overrideWith((ref) => ctrl), + documentRepositoryProvider.overrideWith((ref) => ctrl), ], child: MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, diff --git a/test/widget/pdf_page_area_jump_test.dart b/test/widget/pdf_page_area_jump_test.dart index 302bc81..946483b 100644 --- a/test/widget/pdf_page_area_jump_test.dart +++ b/test/widget/pdf_page_area_jump_test.dart @@ -6,11 +6,11 @@ import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/data/services/export_providers.dart'; import 'package:pdf_signature/l10n/app_localizations.dart'; -import 'package:pdf_signature/data/model/model.dart'; +import 'package:pdf_signature/domain/models/model.dart'; -class _TestPdfController extends PdfController { +class _TestPdfController extends DocumentStateNotifier { _TestPdfController() : super() { - state = PdfState.initial().copyWith( + state = Document.initial().copyWith( loaded: true, pageCount: 6, currentPage: 2, @@ -29,7 +29,7 @@ void main() { overrides: [ useMockViewerProvider.overrideWithValue(true), // Continuous mode is always-on; no page view override needed - pdfProvider.overrideWith((ref) => ctrl), + documentRepositoryProvider.overrideWith((ref) => ctrl), ], child: MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, diff --git a/test/widget/pdf_page_area_test.dart b/test/widget/pdf_page_area_test.dart index 760e92c..62604d7 100644 --- a/test/widget/pdf_page_area_test.dart +++ b/test/widget/pdf_page_area_test.dart @@ -53,10 +53,10 @@ void main() { await tester.pumpWidget(buildHarness(width: 480)); // Open sample and add a normalized placement to page 1 - container.read(pdfProvider.notifier).openSample(); + container.read(documentRepositoryProvider.notifier).openSample(); // One placement at (25% x, 50% y), size 10% x 10% container - .read(pdfProvider.notifier) + .read(documentRepositoryProvider.notifier) .addPlacement( page: 1, rect: const Rect.fromLTWH(0.25, 0.50, 0.10, 0.10), diff --git a/test/widget/regression_signature_tests.dart b/test/widget/regression_signature_tests.dart index 8af4574..e29b9e6 100644 --- a/test/widget/regression_signature_tests.dart +++ b/test/widget/regression_signature_tests.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:pdf_signature/data/repositories/signature_library_repository.dart'; +import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_repository.dart'; import 'package:pdf_signature/data/repositories/pdf_repository.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; @@ -118,11 +118,11 @@ void main() { final container3 = ProviderScope.containerOf(ctx3); final processed = container3.read(processedSignatureImageProvider); expect(processed, isNotNull); - final pdf = container3.read(pdfProvider); + final pdf = container3.read(documentRepositoryProvider); final imgId = pdf.placementsByPage[pdf.currentPage]?.first.asset?.id; expect(imgId, isNotNull); expect(imgId, isNotEmpty); - final lib = container3.read(signatureLibraryProvider); + final lib = container3.read(signatureAssetRepositoryProvider); final match = lib.firstWhere((a) => a.id == imgId); expect(match.bytes, equals(processed)); }); diff --git a/test/widget/welcome_drop_test.dart b/test/widget/welcome_drop_test.dart index 4745a67..d469876 100644 --- a/test/widget/welcome_drop_test.dart +++ b/test/widget/welcome_drop_test.dart @@ -45,7 +45,7 @@ void main() { await tester.pump(); final container = ProviderScope.containerOf(stateful.context); - final pdf = container.read(pdfProvider); + final pdf = container.read(documentRepositoryProvider); expect(pdf.loaded, isTrue); expect(pdf.pickedPdfPath, '/tmp/sample.pdf'); expect(pdf.pickedPdfBytes, bytes);