fix: thumbnail not shown actualy pdf page

This commit is contained in:
insleker 2025-09-12 12:29:23 +08:00
parent c82bb7fa2a
commit 7336ca4d57
43 changed files with 276 additions and 237 deletions

View File

@ -13,7 +13,7 @@ import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pages_sidebar.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pages_sidebar.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
@ -48,11 +48,7 @@ void main() {
(ref) => PreferencesStateNotifier(prefs), (ref) => PreferencesStateNotifier(prefs),
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) => DocumentStateNotifier()..openPicked(pageCount: 3),
DocumentStateNotifier()..openPicked(
path: 'integration_test/data/sample-local-pdf.pdf',
pageCount: 3,
),
), ),
useMockViewerProvider.overrideWith((ref) => false), useMockViewerProvider.overrideWith((ref) => false),
exportServiceProvider.overrideWith((_) => fake), exportServiceProvider.overrideWith((_) => fake),
@ -110,11 +106,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
signatureAssetRepositoryProvider.overrideWith((ref) { signatureAssetRepositoryProvider.overrideWith((ref) {
final c = SignatureAssetRepository(); final c = SignatureAssetRepository();
@ -196,11 +189,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],
@ -239,11 +229,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],
@ -285,11 +272,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],
@ -305,6 +289,14 @@ void main() {
final ctx = tester.element(find.byType(PdfSignatureHomePage)); final ctx = tester.element(find.byType(PdfSignatureHomePage));
final container = ProviderScope.containerOf(ctx); final container = ProviderScope.containerOf(ctx);
expect(container.read(pdfViewModelProvider), 1); expect(container.read(pdfViewModelProvider), 1);
final pagesSidebar = find.byType(PagesSidebar);
expect(pagesSidebar, findsOneWidget);
// Scroll to make page 3 thumbnail visible
await tester.drag(pagesSidebar, const Offset(0, -300));
await tester.pumpAndSettle();
final page3Thumb = find.text('3'); final page3Thumb = find.text('3');
expect(page3Thumb, findsOneWidget); expect(page3Thumb, findsOneWidget);
await tester.tap(page3Thumb); await tester.tap(page3Thumb);
@ -326,11 +318,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],

View File

@ -6,7 +6,7 @@ import 'dart:io';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pages_sidebar.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pages_sidebar.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -34,11 +34,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],
@ -85,11 +82,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],
@ -136,11 +130,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],
@ -159,6 +150,13 @@ void main() {
final container = ProviderScope.containerOf(ctx); final container = ProviderScope.containerOf(ctx);
expect(container.read(pdfViewModelProvider), 1); expect(container.read(pdfViewModelProvider), 1);
final pagesSidebar = find.byType(PagesSidebar);
expect(pagesSidebar, findsOneWidget);
// Scroll to make page 3 thumbnail visible
await tester.drag(pagesSidebar, const Offset(0, -300));
await tester.pumpAndSettle();
final page3Thumbnail = find.text('3'); final page3Thumbnail = find.text('3');
expect(page3Thumbnail, findsOneWidget); expect(page3Thumbnail, findsOneWidget);
await tester.tap(page3Thumbnail); await tester.tap(page3Thumbnail);
@ -181,11 +179,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'integration_test/data/sample-local-pdf.pdf', ..openPicked(pageCount: 3, bytes: pdfBytes),
pageCount: 3,
bytes: pdfBytes,
),
), ),
useMockViewerProvider.overrideWithValue(false), useMockViewerProvider.overrideWithValue(false),
], ],

View File

@ -16,7 +16,6 @@ class DocumentStateNotifier extends StateNotifier<Document> {
} }
void openPicked({ void openPicked({
required String path,
required int pageCount, required int pageCount,
Uint8List? bytes, Uint8List? bytes,
}) { }) {

View File

@ -29,7 +29,7 @@ class PdfViewModel extends StateNotifier<int> {
} }
ref ref
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: path, pageCount: pageCount, bytes: bytes); .openPicked(pageCount: pageCount, bytes: bytes);
ref.read(signatureCardRepositoryProvider.notifier).clearAll(); ref.read(signatureCardRepositoryProvider.notifier).clearAll();
state = 1; // Reset current page to 1 state = 1; // Reset current page to 1
} }

View File

@ -1,11 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'pdf_pages_overview.dart'; import 'thumbnails_view.dart';
class PagesSidebar extends StatelessWidget { class PagesSidebar extends StatelessWidget {
const PagesSidebar({super.key}); const PagesSidebar({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card(margin: EdgeInsets.zero, child: const PdfPagesOverview()); return Card(margin: EdgeInsets.zero, child: const ThumbnailsView());
} }
} }

View File

@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';
import 'pdf_page_overlays.dart'; import 'pdf_page_overlays.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';
// using only adjusted overlay, no direct model imports needed // using only adjusted overlay, no direct model imports needed
import '../../signature/widgets/signature_drag_data.dart'; import '../../signature/widgets/signature_drag_data.dart';

View File

@ -6,7 +6,7 @@ import 'package:pdf_signature/l10n/app_localizations.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'pdf_viewer_widget.dart'; import 'pdf_viewer_widget.dart';
import '../view_model/pdf_view_model.dart'; import '../view_model/pdf_view_model.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
class PdfPageArea extends ConsumerStatefulWidget { class PdfPageArea extends ConsumerStatefulWidget {
const PdfPageArea({ const PdfPageArea({
@ -159,6 +159,7 @@ class _PdfPageAreaState extends ConsumerState<PdfPageArea> {
// Use real PDF viewer // Use real PDF viewer
if (isContinuous) { if (isContinuous) {
final controller = ref.watch(pdfViewerControllerProvider);
return PdfViewerWidget( return PdfViewerWidget(
pageSize: widget.pageSize, pageSize: widget.pageSize,
onDragSignature: widget.onDragSignature, onDragSignature: widget.onDragSignature,
@ -168,6 +169,7 @@ class _PdfPageAreaState extends ConsumerState<PdfPageArea> {
onSelectPlaced: widget.onSelectPlaced, onSelectPlaced: widget.onSelectPlaced,
pageKeyBuilder: _pageKey, pageKeyBuilder: _pageKey,
scrollToPage: _scrollToPage, scrollToPage: _scrollToPage,
controller: controller,
); );
} }
return const SizedBox.shrink(); return const SizedBox.shrink();

View File

@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../domain/models/model.dart'; import '../../../../domain/models/model.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'signature_overlay.dart'; import 'signature_overlay.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
/// Builds all overlays for a given page: placed signatures and the active one. /// Builds all overlays for a given page: placed signatures and the active one.
class PdfPageOverlays extends ConsumerWidget { class PdfPageOverlays extends ConsumerWidget {

View File

@ -1,7 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdfrx/pdfrx.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
class PdfPagesOverview extends ConsumerWidget { class PdfPagesOverview extends ConsumerWidget {
const PdfPagesOverview({super.key}); const PdfPagesOverview({super.key});
@ -9,12 +10,23 @@ class PdfPagesOverview extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final pdf = ref.watch(documentRepositoryProvider); final pdf = ref.watch(documentRepositoryProvider);
ref.watch(useMockViewerProvider); final controller = ref.watch(pdfViewerControllerProvider);
final theme = Theme.of(context); final theme = Theme.of(context);
if (!pdf.loaded) return const SizedBox.shrink(); if (!pdf.loaded || pdf.pickedPdfBytes == null)
return const SizedBox.shrink();
Widget buildList(int pageCount, {Widget Function(int i)? item}) { final documentRef = PdfDocumentRefData(
pdf.pickedPdfBytes!,
sourceName: 'document.pdf',
);
return Container(
color: theme.colorScheme.surface,
child: PdfDocumentViewBuilder(
documentRef: documentRef,
builder: (context, document) {
final pageCount = document?.pages.length ?? 0;
return ListView.separated( return ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
itemCount: pageCount, itemCount: pageCount,
@ -24,9 +36,10 @@ class PdfPagesOverview extends ConsumerWidget {
final isSelected = ref.watch(currentPageProvider) == pageNumber; final isSelected = ref.watch(currentPageProvider) == pageNumber;
return InkWell( return InkWell(
onTap: () { onTap: () {
final controller = ref.read(pdfViewerControllerProvider); controller.goToPage(
if (controller.isReady) pageNumber: pageNumber,
controller.goToPage(pageNumber: pageNumber); anchor: PdfPageAnchor.top,
);
}, },
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
@ -44,24 +57,30 @@ class PdfPagesOverview extends ConsumerWidget {
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(6), padding: const EdgeInsets.all(6),
child: AspectRatio( child: Column(
aspectRatio: 1 / 1.4142, // A4 portrait approx children: [
SizedBox(
height: 180,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(4), borderRadius: BorderRadius.circular(4),
child: child: PdfPageView(
item != null document: document,
? item(index) pageNumber: pageNumber,
: Center(child: Text('$pageNumber')), alignment: Alignment.center,
), ),
), ),
), ),
const SizedBox(height: 4),
Text('$pageNumber', style: theme.textTheme.bodySmall),
],
),
),
), ),
); );
}, },
); );
} },
),
final count = pdf.pageCount == 0 ? 1 : pdf.pageCount; );
return buildList(count);
} }
} }

View File

@ -8,7 +8,7 @@ import 'package:pdf_signature/l10n/app_localizations.dart';
import 'package:multi_split_view/multi_split_view.dart'; import 'package:multi_split_view/multi_split_view.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
import 'package:pdfrx/pdfrx.dart'; import 'package:pdfrx/pdfrx.dart';
import 'draw_canvas.dart'; import 'draw_canvas.dart';
import 'pdf_toolbar.dart'; import 'pdf_toolbar.dart';
@ -31,6 +31,7 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
bool _showPagesSidebar = true; bool _showPagesSidebar = true;
bool _showSignaturesSidebar = true; bool _showSignaturesSidebar = true;
int _zoomLevel = 100; // percentage for display only int _zoomLevel = 100; // percentage for display only
fs.XFile _file = fs.XFile('');
// Split view controller to manage resizable sidebars without remounting the center area. // Split view controller to manage resizable sidebars without remounting the center area.
late final MultiSplitViewController _splitController; late final MultiSplitViewController _splitController;
@ -57,6 +58,9 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
final typeGroup = const fs.XTypeGroup(label: 'PDF', extensions: ['pdf']); final typeGroup = const fs.XTypeGroup(label: 'PDF', extensions: ['pdf']);
final file = await fs.openFile(acceptedTypeGroups: [typeGroup]); final file = await fs.openFile(acceptedTypeGroups: [typeGroup]);
if (file != null) { if (file != null) {
setState(() {
_file = file;
});
Uint8List? bytes; Uint8List? bytes;
try { try {
bytes = await file.readAsBytes(); bytes = await file.readAsBytes();
@ -75,7 +79,7 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
} }
ref ref
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: file.path, pageCount: pageCount, bytes: bytes); .openPicked(pageCount: pageCount, bytes: bytes);
} }
} }
@ -331,7 +335,7 @@ class _PdfSignatureHomePageState extends ConsumerState<PdfSignatureHomePage> {
}); });
}, },
zoomLevel: _zoomLevel, zoomLevel: _zoomLevel,
fileName: 'mock.pdf', fileName: _file.name,
showPagesSidebar: _showPagesSidebar, showPagesSidebar: _showPagesSidebar,
showSignaturesSidebar: _showSignaturesSidebar, showSignaturesSidebar: _showSignaturesSidebar,
onTogglePagesSidebar: onTogglePagesSidebar:

View File

@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
class PdfToolbar extends ConsumerStatefulWidget { class PdfToolbar extends ConsumerStatefulWidget {
const PdfToolbar({ const PdfToolbar({

View File

@ -5,8 +5,8 @@ import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';
import 'pdf_page_overlays.dart'; import 'pdf_page_overlays.dart';
import './pdf_mock_continuous_list.dart'; import './pdf_mock_continuous_list.dart';
import '../../signature/widgets/signature_drag_data.dart'; import '../view_model/pdf_providers.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_view_model.dart';
class PdfViewerWidget extends ConsumerStatefulWidget { class PdfViewerWidget extends ConsumerStatefulWidget {
const PdfViewerWidget({ const PdfViewerWidget({
@ -19,6 +19,7 @@ class PdfViewerWidget extends ConsumerStatefulWidget {
required this.onSelectPlaced, required this.onSelectPlaced,
this.pageKeyBuilder, this.pageKeyBuilder,
this.scrollToPage, this.scrollToPage,
required this.controller,
}); });
final Size pageSize; final Size pageSize;
@ -29,22 +30,21 @@ class PdfViewerWidget extends ConsumerStatefulWidget {
final ValueChanged<int?> onSelectPlaced; final ValueChanged<int?> onSelectPlaced;
final GlobalKey Function(int page)? pageKeyBuilder; final GlobalKey Function(int page)? pageKeyBuilder;
final void Function(int page)? scrollToPage; final void Function(int page)? scrollToPage;
final PdfViewerController controller;
@override @override
ConsumerState<PdfViewerWidget> createState() => _PdfViewerWidgetState(); ConsumerState<PdfViewerWidget> createState() => _PdfViewerWidgetState();
} }
class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> { class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
PdfViewerController? _controller;
PdfDocumentRef? _documentRef; PdfDocumentRef? _documentRef;
// Public getter for testing the actual viewer page // Public getter for testing the actual viewer page
int? get viewerCurrentPage => _controller?.pageNumber; int? get viewerCurrentPage => widget.controller.pageNumber;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_controller = PdfViewerController();
} }
@override @override
@ -99,14 +99,12 @@ class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
); );
} }
return Stack( return PdfViewer(
children: [
PdfViewer(
_documentRef!, _documentRef!,
key: const Key( key: const Key(
'pdf_continuous_mock_list', 'pdf_continuous_mock_list',
), // Keep the same key for test compatibility ), // Keep the same key for test compatibility
controller: _controller, controller: widget.controller,
params: PdfViewerParams( params: PdfViewerParams(
onViewerReady: (document, controller) { onViewerReady: (document, controller) {
// Update page count in repository // Update page count in repository
@ -117,56 +115,13 @@ class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
onPageChanged: (page) { onPageChanged: (page) {
if (page != null) { if (page != null) {
ref.read(currentPageProvider.notifier).state = page; ref.read(currentPageProvider.notifier).state = page;
// Also update the view model to keep them in sync
ref.read(pdfViewModelProvider.notifier).jumpToPage(page);
} }
}, },
), viewerOverlayBuilder: (context, size, handle) {
), return [
// Drag target for dropping signatures PdfPageOverlays(
Positioned.fill(
child: DragTarget<SignatureDragData>(
onAcceptWithDetails: (details) {
final dragData = details.data;
// For real PDF viewer, we need to calculate which page was dropped on
// This is a simplified implementation - in a real app you'd need to
// determine the exact page and position within that page
final currentPage = ref.read(currentPageProvider);
// Create a default rect for the signature (can be adjusted later)
final rect = const Rect.fromLTWH(0.1, 0.1, 0.2, 0.1);
// Add placement to the document
ref
.read(documentRepositoryProvider.notifier)
.addPlacement(
page: currentPage,
rect: rect,
asset: dragData.card?.asset,
rotationDeg: dragData.card?.rotationDeg ?? 0.0,
graphicAdjust: dragData.card?.graphicAdjust,
);
},
builder: (context, candidateData, rejectedData) {
return Container(
color:
candidateData.isNotEmpty
? Colors.blue.withOpacity(0.1)
: Colors.transparent,
);
},
),
),
// Add signature overlays on top
Positioned.fill(
child: Consumer(
builder: (context, ref, _) {
final visible = ref.watch(signatureVisibilityProvider);
if (!visible) return const SizedBox.shrink();
// For now, just add a simple overlay for the first page
// This is a simplified version - in a real implementation you'd need
// to handle overlays for each page properly
return PdfPageOverlays(
pageSize: widget.pageSize, pageSize: widget.pageSize,
pageNumber: ref.watch(currentPageProvider), pageNumber: ref.watch(currentPageProvider),
onDragSignature: widget.onDragSignature, onDragSignature: widget.onDragSignature,
@ -174,11 +129,10 @@ class _PdfViewerWidgetState extends ConsumerState<PdfViewerWidget> {
onConfirmSignature: widget.onConfirmSignature, onConfirmSignature: widget.onConfirmSignature,
onClearActiveOverlay: widget.onClearActiveOverlay, onClearActiveOverlay: widget.onClearActiveOverlay,
onSelectPlaced: widget.onSelectPlaced, onSelectPlaced: widget.onSelectPlaced,
); ),
];
}, },
), ),
),
],
); );
} }
} }

View File

@ -8,7 +8,7 @@ import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'
import 'package:pdf_signature/data/repositories/signature_card_repository.dart'; import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
import 'image_editor_dialog.dart'; import 'image_editor_dialog.dart';
import '../../signature/widgets/signature_card.dart'; import '../../signature/widgets/signature_card.dart';
import 'pdf_providers.dart'; import '../view_model/pdf_providers.dart';
/// Data for drag-and-drop is in signature_drag_data.dart /// Data for drag-and-drop is in signature_drag_data.dart

View File

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdfrx/pdfrx.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart';
import '../view_model/pdf_providers.dart';
class ThumbnailsView extends ConsumerWidget {
const ThumbnailsView({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final pdf = ref.watch(documentRepositoryProvider);
final controller = ref.watch(pdfViewerControllerProvider);
final theme = Theme.of(context);
if (!pdf.loaded || pdf.pickedPdfBytes == null)
return const SizedBox.shrink();
final documentRef = PdfDocumentRefData(
pdf.pickedPdfBytes!,
sourceName: 'document.pdf',
);
return Container(
color: theme.colorScheme.surface,
child: PdfDocumentViewBuilder(
documentRef: documentRef,
builder: (context, document) {
final pageCount = document?.pages.length ?? 0;
return ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
itemCount: pageCount,
separatorBuilder: (_, _) => const SizedBox(height: 8),
itemBuilder: (context, index) {
final pageNumber = index + 1;
final isSelected = ref.watch(currentPageProvider) == pageNumber;
return InkWell(
onTap: () {
controller.goToPage(
pageNumber: pageNumber,
anchor: PdfPageAnchor.top,
);
},
child: DecoratedBox(
decoration: BoxDecoration(
color:
isSelected
? theme.colorScheme.primaryContainer
: theme.cardColor,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color:
isSelected
? theme.colorScheme.primary
: theme.dividerColor,
),
),
child: Padding(
padding: const EdgeInsets.all(6),
child: Column(
children: [
SizedBox(
height: 180,
child: ClipRRect(
borderRadius: BorderRadius.circular(4),
child: PdfPageView(
document: document,
pageNumber: pageNumber,
alignment: Alignment.center,
),
),
),
const SizedBox(height: 4),
Text('$pageNumber', style: theme.textTheme.bodySmall),
],
),
),
),
);
},
);
},
),
);
}
}

View File

@ -21,7 +21,7 @@ class WelcomeViewModel {
} }
ref ref
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: path, pageCount: pageCount, bytes: bytes); .openPicked(pageCount: pageCount, bytes: bytes);
ref.read(signatureCardRepositoryProvider.notifier).clearAll(); ref.read(signatureCardRepositoryProvider.notifier).clearAll();
} }
} }

View File

@ -6,7 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:pdf_signature/app.dart'; import 'package:pdf_signature/app.dart';
import 'package:pdf_signature/data/repositories/preferences_repository.dart'; import 'package:pdf_signature/data/repositories/preferences_repository.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart';
import 'package:pdf_signature/data/services/export_service.dart'; import 'package:pdf_signature/data/services/export_service.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';

View File

@ -14,7 +14,7 @@ Future<void> aDocumentIsOpenAndContainsAtLeastOneSignaturePlacement(
TestWorld.container = container; TestWorld.container = container;
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'test.pdf', pageCount: 5); .openPicked(pageCount: 5);
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.addPlacement( .addPlacement(

View File

@ -15,7 +15,7 @@ aDocumentIsOpenAndContainsMultiplePlacedSignaturePlacementsAcrossPages(
TestWorld.container = container; TestWorld.container = container;
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'multi.pdf', pageCount: 5); .openPicked(pageCount: 5);
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.addPlacement( .addPlacement(

View File

@ -11,6 +11,6 @@ Future<void> aDocumentIsOpenWithNoSignaturePlacementsPlaced(
TestWorld.container = container; TestWorld.container = container;
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'empty.pdf', pageCount: 5); .openPicked(pageCount: 5);
// No placements added // No placements added
} }

View File

@ -4,7 +4,7 @@ import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/data/repositories/signature_card_repository.dart'; import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';
@ -18,9 +18,7 @@ Future<void> aMultipageDocumentIsOpen(WidgetTester tester) async {
container.read(signatureCardRepositoryProvider.notifier).state = [ container.read(signatureCardRepositoryProvider.notifier).state = [
SignatureCard.initial(), SignatureCard.initial(),
]; ];
container container.read(documentRepositoryProvider.notifier).openPicked(pageCount: 5);
.read(documentRepositoryProvider.notifier)
.openPicked(path: 'mock.pdf', pageCount: 5);
// Reset page state providers // Reset page state providers
try { try {
container.read(currentPageProvider.notifier).state = 1; container.read(currentPageProvider.notifier).state = 1;

View File

@ -11,5 +11,5 @@ Future<void> aSampleMultipageDocument5PagesIsAvailable(
TestWorld.container = container; TestWorld.container = container;
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'sample.pdf', pageCount: 5); .openPicked(pageCount: 5);
} }

View File

@ -17,7 +17,7 @@ Future<void> aSignatureAssetIsPlacedOnThePage(WidgetTester tester) async {
if (!container.read(documentRepositoryProvider).loaded) { if (!container.read(documentRepositoryProvider).loaded) {
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'mock.pdf', pageCount: 5); .openPicked(pageCount: 5);
} }
// Get or create an asset // Get or create an asset

View File

@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -7,7 +7,7 @@ import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';
import 'package:pdf_signature/data/repositories/signature_card_repository.dart'; import 'package:pdf_signature/data/repositories/signature_card_repository.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import '_world.dart'; import '_world.dart';
class _BridgedSignatureCardStateNotifier extends SignatureCardStateNotifier { class _BridgedSignatureCardStateNotifier extends SignatureCardStateNotifier {

View File

@ -2,7 +2,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import '_world.dart'; import '_world.dart';
/// Usage: the last page is displayed (page {5}) /// Usage: the last page is displayed (page {5})

View File

@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -22,7 +22,7 @@ theUserDragsItOnThePageOfTheDocumentToPlaceSignaturePlacementsInMultipleLocation
if (!container.read(documentRepositoryProvider).loaded) { if (!container.read(documentRepositoryProvider).loaded) {
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'mock.pdf', pageCount: 5); .openPicked(pageCount: 5);
} }
container container

View File

@ -21,7 +21,7 @@ theUserDragsThisSignatureCardOnThePageOfTheDocumentToPlaceASignaturePlacement(
if (!container.read(documentRepositoryProvider).loaded) { if (!container.read(documentRepositoryProvider).loaded) {
container container
.read(documentRepositoryProvider.notifier) .read(documentRepositoryProvider.notifier)
.openPicked(path: 'mock.pdf', pageCount: 5); .openPicked(pageCount: 5);
} }
// Get or create an asset // Get or create an asset

View File

@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -4,7 +4,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -12,7 +12,7 @@ Future<void> theUserPlacesItInMultipleLocationsInTheDocument(
TestWorld.container = container; TestWorld.container = container;
final notifier = container.read(documentRepositoryProvider.notifier); final notifier = container.read(documentRepositoryProvider.notifier);
// Always open a fresh doc to avoid state bleed between scenarios // Always open a fresh doc to avoid state bleed between scenarios
notifier.openPicked(path: 'mock.pdf', pageCount: 6); notifier.openPicked(pageCount: 6);
// Place two on page 2 and one on page 4 // Place two on page 2 and one on page 4
notifier.addPlacement(page: 2, rect: const Rect.fromLTWH(10, 10, 80, 40)); notifier.addPlacement(page: 2, rect: const Rect.fromLTWH(10, 10, 80, 40));
notifier.addPlacement(page: 2, rect: const Rect.fromLTWH(120, 50, 80, 40)); notifier.addPlacement(page: 2, rect: const Rect.fromLTWH(120, 50, 80, 40));

View File

@ -10,9 +10,7 @@ Future<void> theUserSelects(WidgetTester tester, dynamic file) async {
final container = ProviderContainer(); final container = ProviderContainer();
TestWorld.container = container; TestWorld.container = container;
// Mark page for signing to enable signature ops // Mark page for signing to enable signature ops
container container.read(documentRepositoryProvider.notifier).openPicked(pageCount: 1);
.read(documentRepositoryProvider.notifier)
.openPicked(path: 'mock.pdf', pageCount: 1);
// For invalid/unsupported/empty selections we do NOT set image bytes. // For invalid/unsupported/empty selections we do NOT set image bytes.
// This simulates a failed load and keeps rect null. // This simulates a failed load and keeps rect null.
final token = file.toString(); final token = file.toString();

View File

@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import '_world.dart'; import '_world.dart';

View File

@ -22,9 +22,7 @@ Future<void> threeSignaturePlacementsArePlacedOnTheCurrentPage(
container.read(signatureCardRepositoryProvider.notifier).state = [ container.read(signatureCardRepositoryProvider.notifier).state = [
SignatureCard.initial(), SignatureCard.initial(),
]; ];
container container.read(documentRepositoryProvider.notifier).openPicked(pageCount: 5);
.read(documentRepositoryProvider.notifier)
.openPicked(path: 'mock.pdf', pageCount: 5);
final pdfN = container.read(documentRepositoryProvider.notifier); final pdfN = container.read(documentRepositoryProvider.notifier);
final page = container.read(pdfViewModelProvider); final page = container.read(pdfViewModelProvider);
pdfN.addPlacement( pdfN.addPlacement(

View File

@ -8,7 +8,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:pdf_signature/data/services/export_service.dart'; import 'package:pdf_signature/data/services/export_service.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart';
import 'package:pdf_signature/data/repositories/preferences_repository.dart'; import 'package:pdf_signature/data/repositories/preferences_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
@ -55,11 +55,8 @@ void main() {
), ),
documentRepositoryProvider.overrideWith( documentRepositoryProvider.overrideWith(
(ref) => (ref) =>
DocumentStateNotifier()..openPicked( DocumentStateNotifier()
path: 'test.pdf', ..openPicked(pageCount: 5, bytes: Uint8List(0)),
pageCount: 5,
bytes: Uint8List(0),
),
), ),
useMockViewerProvider.overrideWith((ref) => true), useMockViewerProvider.overrideWith((ref) => true),
exportServiceProvider.overrideWith((_) => fake), exportServiceProvider.overrideWith((_) => fake),

View File

@ -5,7 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:image/image.dart' as img; import 'package:image/image.dart' as img;
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/ui_services.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/data/repositories/signature_asset_repository.dart'; import 'package:pdf_signature/data/repositories/signature_asset_repository.dart';

View File

@ -5,7 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_screen.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';

View File

@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';

View File

@ -4,7 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';

View File

@ -6,7 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart'; import 'package:pdf_signature/ui/features/pdf/widgets/pdf_page_area.dart';
import 'package:pdf_signature/data/repositories/document_repository.dart'; import 'package:pdf_signature/data/repositories/document_repository.dart';
import 'package:pdf_signature/ui/features/pdf/widgets/pdf_providers.dart'; import 'package:pdf_signature/ui/features/pdf/view_model/pdf_providers.dart';
import 'package:pdf_signature/l10n/app_localizations.dart'; import 'package:pdf_signature/l10n/app_localizations.dart';
import 'package:pdf_signature/domain/models/model.dart'; import 'package:pdf_signature/domain/models/model.dart';