refactor: update PDF view model and routing for improved session management
This commit is contained in:
parent
6652de28bf
commit
feaf7aee9f
|
|
@ -61,17 +61,17 @@ 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);
|
||||||
final vm = container.read(pdfViewModelProvider);
|
final vm = container.read(pdfViewModelProvider);
|
||||||
expect(vm, 1);
|
expect(vm.currentPage, 1);
|
||||||
|
|
||||||
container.read(pdfViewModelProvider.notifier).jumpToPage(2);
|
container.read(pdfViewModelProvider.notifier).jumpToPage(2);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(milliseconds: 120));
|
await tester.pump(const Duration(milliseconds: 120));
|
||||||
expect(container.read(pdfViewModelProvider), 2);
|
expect(container.read(pdfViewModelProvider).currentPage, 2);
|
||||||
|
|
||||||
container.read(pdfViewModelProvider.notifier).jumpToPage(3);
|
container.read(pdfViewModelProvider.notifier).jumpToPage(3);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(milliseconds: 120));
|
await tester.pump(const Duration(milliseconds: 120));
|
||||||
expect(container.read(pdfViewModelProvider), 3);
|
expect(container.read(pdfViewModelProvider).currentPage, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('PDF View: zoom in/out', (tester) async {
|
testWidgets('PDF View: zoom in/out', (tester) async {
|
||||||
|
|
@ -166,7 +166,7 @@ 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).currentPage, 1);
|
||||||
|
|
||||||
final pagesSidebar = find.byType(PagesSidebar);
|
final pagesSidebar = find.byType(PagesSidebar);
|
||||||
expect(pagesSidebar, findsOneWidget);
|
expect(pagesSidebar, findsOneWidget);
|
||||||
|
|
@ -180,7 +180,7 @@ void main() {
|
||||||
await tester.tap(page3Thumbnail);
|
await tester.tap(page3Thumbnail);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(container.read(pdfViewModelProvider), 3);
|
expect(container.read(pdfViewModelProvider).currentPage, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('PDF View: thumbnails scroll and select', (tester) async {
|
testWidgets('PDF View: thumbnails scroll and select', (tester) async {
|
||||||
|
|
@ -221,7 +221,7 @@ 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).currentPage, 1);
|
||||||
|
|
||||||
final pagesSidebar = find.byType(PagesSidebar);
|
final pagesSidebar = find.byType(PagesSidebar);
|
||||||
expect(pagesSidebar, findsOneWidget);
|
expect(pagesSidebar, findsOneWidget);
|
||||||
|
|
@ -229,13 +229,84 @@ void main() {
|
||||||
await tester.drag(pagesSidebar, const Offset(0, -200));
|
await tester.drag(pagesSidebar, const Offset(0, -200));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(find.text('1'), findsOneWidget);
|
// Page number '1' may appear in multiple text widgets (e.g., overlay/toolbar); restrict to sidebar.
|
||||||
expect(container.read(pdfViewModelProvider), 1);
|
final page1InSidebar = find.descendant(
|
||||||
|
of: pagesSidebar,
|
||||||
|
matching: find.text('1'),
|
||||||
|
);
|
||||||
|
expect(page1InSidebar, findsOneWidget);
|
||||||
|
expect(container.read(pdfViewModelProvider).currentPage, 1);
|
||||||
|
|
||||||
// Select page 2 thumbnail and verify page changes
|
// Select page 2 thumbnail and verify page changes
|
||||||
await tester.tap(find.text('2'));
|
final page2InSidebar = find.descendant(
|
||||||
|
of: pagesSidebar,
|
||||||
|
matching: find.text('2'),
|
||||||
|
);
|
||||||
|
await tester.tap(page2InSidebar);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(container.read(pdfViewModelProvider), 2);
|
expect(container.read(pdfViewModelProvider).currentPage, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('PDF View: scroll thumbnails to reveal and select last page', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
final pdfBytes =
|
||||||
|
await File('integration_test/data/sample-local-pdf.pdf').readAsBytes();
|
||||||
|
SharedPreferences.setMockInitialValues({});
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
ProviderScope(
|
||||||
|
overrides: [
|
||||||
|
preferencesRepositoryProvider.overrideWith(
|
||||||
|
(ref) => PreferencesStateNotifier(prefs),
|
||||||
|
),
|
||||||
|
documentRepositoryProvider.overrideWith(
|
||||||
|
(ref) =>
|
||||||
|
DocumentStateNotifier()
|
||||||
|
..openPicked(pageCount: 3, bytes: pdfBytes),
|
||||||
|
),
|
||||||
|
pdfViewModelProvider.overrideWith(
|
||||||
|
(ref) => PdfViewModel(ref, useMockViewer: false),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: MaterialApp(
|
||||||
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
|
supportedLocales: AppLocalizations.supportedLocales,
|
||||||
|
locale: const Locale('en'),
|
||||||
|
home: PdfSignatureHomePage(
|
||||||
|
onPickPdf: () async {},
|
||||||
|
onClosePdf: () {},
|
||||||
|
currentFile: fs.XFile('test.pdf'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final ctx = tester.element(find.byType(PdfSignatureHomePage));
|
||||||
|
final container = ProviderScope.containerOf(ctx);
|
||||||
|
expect(container.read(pdfViewModelProvider).currentPage, 1);
|
||||||
|
|
||||||
|
final pagesSidebar = find.byType(PagesSidebar);
|
||||||
|
expect(pagesSidebar, findsOneWidget);
|
||||||
|
|
||||||
|
// Ensure page 3 not initially in view by trying to find it and allowing that it might be offstage.
|
||||||
|
// Perform a scroll/drag to bring page 3 into view.
|
||||||
|
await tester.drag(pagesSidebar, const Offset(0, -400));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final page3 = find.descendant(of: pagesSidebar, matching: find.text('3'));
|
||||||
|
expect(page3, findsOneWidget);
|
||||||
|
await tester.tap(page3);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(container.read(pdfViewModelProvider).currentPage, 3);
|
||||||
|
|
||||||
|
// Scroll back upward and verify selection persists.
|
||||||
|
await tester.drag(pagesSidebar, const Offset(0, 300));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(container.read(pdfViewModelProvider).currentPage, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO: Scroll Thumbs
|
//TODO: Scroll Thumbs
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ class GraphicAdjust {
|
||||||
|
|
||||||
const GraphicAdjust({
|
const GraphicAdjust({
|
||||||
this.contrast = 1.0,
|
this.contrast = 1.0,
|
||||||
this.brightness = 0.0,
|
this.brightness = 1.0,
|
||||||
this.bgRemoval = false,
|
this.bgRemoval = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,126 +5,50 @@ import 'package:go_router/go_router.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/welcome/widgets/welcome_screen.dart';
|
import 'package:pdf_signature/ui/features/welcome/widgets/welcome_screen.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_card_repository.dart';
|
import 'package:pdf_signature/ui/features/pdf/view_model/pdf_view_model.dart';
|
||||||
import 'package:file_selector/file_selector.dart' as fs;
|
|
||||||
import 'package:pdfrx/pdfrx.dart';
|
|
||||||
|
|
||||||
class PdfManager {
|
// PdfManager removed: responsibilities moved into PdfSessionViewModel.
|
||||||
final DocumentStateNotifier _documentNotifier;
|
|
||||||
final SignatureCardStateNotifier _signatureCardNotifier;
|
|
||||||
final GoRouter _router;
|
|
||||||
|
|
||||||
fs.XFile _currentFile = fs.XFile('');
|
|
||||||
|
|
||||||
PdfManager({
|
|
||||||
required DocumentStateNotifier documentNotifier,
|
|
||||||
required SignatureCardStateNotifier signatureCardNotifier,
|
|
||||||
required GoRouter router,
|
|
||||||
}) : _documentNotifier = documentNotifier,
|
|
||||||
_signatureCardNotifier = signatureCardNotifier,
|
|
||||||
_router = router;
|
|
||||||
|
|
||||||
fs.XFile get currentFile => _currentFile;
|
|
||||||
|
|
||||||
Future<void> openPdf({String? path, Uint8List? bytes}) async {
|
|
||||||
int pageCount = 1; // default
|
|
||||||
if (bytes != null) {
|
|
||||||
try {
|
|
||||||
final doc = await PdfDocument.openData(bytes);
|
|
||||||
pageCount = doc.pages.length;
|
|
||||||
} catch (_) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update file reference if path is provided
|
|
||||||
if (path != null) {
|
|
||||||
_currentFile = fs.XFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
_documentNotifier.openPicked(pageCount: pageCount, bytes: bytes);
|
|
||||||
_signatureCardNotifier.clearAll();
|
|
||||||
|
|
||||||
// Navigate to PDF screen after successfully opening PDF
|
|
||||||
_router.go('/pdf');
|
|
||||||
}
|
|
||||||
|
|
||||||
void closePdf() {
|
|
||||||
_documentNotifier.close();
|
|
||||||
_signatureCardNotifier.clearAll();
|
|
||||||
_currentFile = fs.XFile('');
|
|
||||||
|
|
||||||
// Navigate back to welcome screen when closing PDF
|
|
||||||
_router.go('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> pickAndOpenPdf() async {
|
|
||||||
final typeGroup = const fs.XTypeGroup(label: 'PDF', extensions: ['pdf']);
|
|
||||||
final file = await fs.openFile(acceptedTypeGroups: [typeGroup]);
|
|
||||||
if (file != null) {
|
|
||||||
Uint8List? bytes;
|
|
||||||
try {
|
|
||||||
bytes = await file.readAsBytes();
|
|
||||||
} catch (_) {
|
|
||||||
bytes = null;
|
|
||||||
}
|
|
||||||
await openPdf(path: file.path, bytes: bytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final routerProvider = Provider<GoRouter>((ref) {
|
final routerProvider = Provider<GoRouter>((ref) {
|
||||||
// Create PdfManager instance with dependencies
|
// Determine initial location based on current document state.
|
||||||
final documentNotifier = ref.read(documentRepositoryProvider.notifier);
|
// Access the state via the provider (not via the notifier's protected .state).
|
||||||
final signatureCardNotifier = ref.read(
|
final docState = ref.read(documentRepositoryProvider);
|
||||||
signatureCardRepositoryProvider.notifier,
|
final initialLocation = docState.loaded ? '/pdf' : '/';
|
||||||
);
|
// Session view model will be obtained inside each route builder; no shared
|
||||||
|
// late variable (avoids LateInitializationError on rebuilds).
|
||||||
|
|
||||||
// Create a navigator key for the router
|
|
||||||
final navigatorKey = GlobalKey<NavigatorState>();
|
final navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
late final GoRouter router; // declare before use in builders
|
||||||
// Create a late variable for the router
|
|
||||||
late final GoRouter router;
|
|
||||||
|
|
||||||
// Create PdfManager with router dependency (will be set after router creation)
|
|
||||||
late final PdfManager pdfManager;
|
|
||||||
|
|
||||||
// If tests pre-load a document, start at /pdf so sidebars and controls
|
|
||||||
// are present immediately.
|
|
||||||
final initialLocation = documentNotifier.debugState.loaded ? '/pdf' : '/';
|
|
||||||
|
|
||||||
router = GoRouter(
|
router = GoRouter(
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
routes: [
|
routes: [
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/',
|
path: '/',
|
||||||
builder:
|
builder: (context, state) {
|
||||||
(context, state) => WelcomeScreen(
|
final sessionVm = ref.read(pdfSessionViewModelProvider(router));
|
||||||
onPickPdf: () => pdfManager.pickAndOpenPdf(),
|
return WelcomeScreen(
|
||||||
onOpenPdf:
|
onPickPdf: () => sessionVm.pickAndOpenPdf(),
|
||||||
({String? path, Uint8List? bytes, String? fileName}) =>
|
onOpenPdf:
|
||||||
pdfManager.openPdf(path: path, bytes: bytes),
|
({String? path, Uint8List? bytes, String? fileName}) =>
|
||||||
),
|
sessionVm.openPdf(path: path, bytes: bytes),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/pdf',
|
path: '/pdf',
|
||||||
builder:
|
builder: (context, state) {
|
||||||
(context, state) => PdfSignatureHomePage(
|
final sessionVm = ref.read(pdfSessionViewModelProvider(router));
|
||||||
onPickPdf: () => pdfManager.pickAndOpenPdf(),
|
return PdfSignatureHomePage(
|
||||||
onClosePdf: () => pdfManager.closePdf(),
|
onPickPdf: () => sessionVm.pickAndOpenPdf(),
|
||||||
currentFile: pdfManager.currentFile,
|
onClosePdf: () => sessionVm.closePdf(),
|
||||||
),
|
currentFile: sessionVm.currentFile,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
initialLocation: initialLocation,
|
initialLocation: initialLocation,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Now create PdfManager with the router
|
|
||||||
pdfManager = PdfManager(
|
|
||||||
documentNotifier: documentNotifier,
|
|
||||||
signatureCardNotifier: signatureCardNotifier,
|
|
||||||
router: router,
|
|
||||||
);
|
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ 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/domain/models/model.dart';
|
import 'package:pdf_signature/domain/models/model.dart';
|
||||||
import 'package:pdfrx/pdfrx.dart';
|
import 'package:pdfrx/pdfrx.dart';
|
||||||
|
import 'package:file_selector/file_selector.dart' as fs;
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
class PdfViewModel extends ChangeNotifier {
|
class PdfViewModel extends ChangeNotifier {
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
|
|
@ -62,28 +64,8 @@ class PdfViewModel extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> openPdf({required String path, Uint8List? bytes}) async {
|
|
||||||
int pageCount = 1;
|
|
||||||
if (bytes != null) {
|
|
||||||
try {
|
|
||||||
final doc = await PdfDocument.openData(bytes);
|
|
||||||
pageCount = doc.pages.length;
|
|
||||||
} catch (_) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ref
|
|
||||||
.read(documentRepositoryProvider.notifier)
|
|
||||||
.openPicked(pageCount: pageCount, bytes: bytes);
|
|
||||||
clearAllSignatureCards();
|
|
||||||
|
|
||||||
currentPage = 1; // Reset current page to 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Document repository methods
|
// Document repository methods
|
||||||
void closeDocument() {
|
// Lifecycle (open/close) removed: handled exclusively by PdfSessionViewModel.
|
||||||
ref.read(documentRepositoryProvider.notifier).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPageCount(int count) {
|
void setPageCount(int count) {
|
||||||
ref.read(documentRepositoryProvider.notifier).setPageCount(count);
|
ref.read(documentRepositoryProvider.notifier).setPageCount(count);
|
||||||
|
|
@ -197,3 +179,63 @@ class PdfViewModel extends ChangeNotifier {
|
||||||
final pdfViewModelProvider = ChangeNotifierProvider<PdfViewModel>((ref) {
|
final pdfViewModelProvider = ChangeNotifierProvider<PdfViewModel>((ref) {
|
||||||
return PdfViewModel(ref);
|
return PdfViewModel(ref);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// ViewModel managing PDF session lifecycle (file picking/open/close) and
|
||||||
|
/// navigation. Replaces the previous PdfManager helper.
|
||||||
|
class PdfSessionViewModel extends ChangeNotifier {
|
||||||
|
final Ref ref;
|
||||||
|
final GoRouter router;
|
||||||
|
fs.XFile _currentFile = fs.XFile('');
|
||||||
|
|
||||||
|
PdfSessionViewModel({required this.ref, required this.router});
|
||||||
|
|
||||||
|
fs.XFile get currentFile => _currentFile;
|
||||||
|
|
||||||
|
Future<void> pickAndOpenPdf() async {
|
||||||
|
final typeGroup = const fs.XTypeGroup(label: 'PDF', extensions: ['pdf']);
|
||||||
|
final file = await fs.openFile(acceptedTypeGroups: [typeGroup]);
|
||||||
|
if (file != null) {
|
||||||
|
Uint8List? bytes;
|
||||||
|
try {
|
||||||
|
bytes = await file.readAsBytes();
|
||||||
|
} catch (_) {
|
||||||
|
bytes = null;
|
||||||
|
}
|
||||||
|
await openPdf(path: file.path, bytes: bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> openPdf({String? path, Uint8List? bytes}) async {
|
||||||
|
int pageCount = 1; // default
|
||||||
|
if (bytes != null) {
|
||||||
|
try {
|
||||||
|
final doc = await PdfDocument.openData(bytes);
|
||||||
|
pageCount = doc.pages.length;
|
||||||
|
} catch (_) {
|
||||||
|
// ignore invalid bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (path != null) {
|
||||||
|
_currentFile = fs.XFile(path);
|
||||||
|
}
|
||||||
|
ref
|
||||||
|
.read(documentRepositoryProvider.notifier)
|
||||||
|
.openPicked(pageCount: pageCount, bytes: bytes);
|
||||||
|
ref.read(signatureCardRepositoryProvider.notifier).clearAll();
|
||||||
|
router.go('/pdf');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void closePdf() {
|
||||||
|
ref.read(documentRepositoryProvider.notifier).close();
|
||||||
|
ref.read(signatureCardRepositoryProvider.notifier).clearAll();
|
||||||
|
_currentFile = fs.XFile('');
|
||||||
|
router.go('/');
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final pdfSessionViewModelProvider =
|
||||||
|
ChangeNotifierProvider.family<PdfSessionViewModel, GoRouter>((ref, router) {
|
||||||
|
return PdfSessionViewModel(ref: ref, router: router);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,23 @@
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.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:go_router/go_router.dart';
|
||||||
|
import 'package:pdf_signature/routing/router.dart';
|
||||||
|
|
||||||
class WelcomeViewModel {
|
class WelcomeViewModel {
|
||||||
final Ref ref;
|
final Ref ref;
|
||||||
|
final GoRouter router;
|
||||||
|
|
||||||
WelcomeViewModel(this.ref);
|
WelcomeViewModel(this.ref, this.router);
|
||||||
|
|
||||||
Future<void> openPdf({required String path, Uint8List? bytes}) async {
|
Future<void> openPdf({required String path, Uint8List? bytes}) async {
|
||||||
await ref
|
// Use PdfSessionViewModel to open and navigate.
|
||||||
.read(pdfViewModelProvider.notifier)
|
final session = ref.read(pdfSessionViewModelProvider(router));
|
||||||
.openPdf(path: path, bytes: bytes);
|
await session.openPdf(path: path, bytes: bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final welcomeViewModelProvider = Provider<WelcomeViewModel>((ref) {
|
final welcomeViewModelProvider = Provider<WelcomeViewModel>((ref) {
|
||||||
return WelcomeViewModel(ref);
|
final router = ref.read(routerProvider);
|
||||||
|
return WelcomeViewModel(ref, router);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue