Line data Source code
1 : part of '../main.dart';
2 :
3 : /// This widget handles most of the routing work
4 : /// It gives you access to the [routes] attribute where you can start
5 : /// building your routes using [VRouteElement]s
6 : ///
7 : /// Note that this widget also acts as a [WidgetsApp] so you can pass
8 : /// it every argument that you would expect in [WidgetsApp]
9 : class WidgetsVRouter extends StatefulWidget
10 : with VRouteElement, VRouteElementSingleSubRoute {
11 : /// This list holds every possible routes of your app
12 : final List<VRouteElement> routes;
13 :
14 : /// If implemented, this becomes the default transition for every route transition
15 : /// except those who implement there own buildTransition
16 : /// Also see:
17 : /// * [VRouteElement.buildTransition] for custom local transitions
18 : ///
19 : /// Note that if this is not implemented, every route which does not implement
20 : /// its own buildTransition will be given a default transition: this of a
21 : /// [MaterialPage] or a [CupertinoPage] depending on the platform
22 : final Widget Function(Animation<double> animation,
23 : Animation<double> secondaryAnimation, Widget child)? buildTransition;
24 :
25 : /// The duration of [VRouter.buildTransition]
26 : final Duration? transitionDuration;
27 :
28 : /// The reverse duration of [VRouter.buildTransition]
29 : final Duration? reverseTransitionDuration;
30 :
31 : /// Two router mode are possible:
32 : /// - "hash": This is the default, the url will be serverAddress/#/localUrl
33 : /// - "history": This will display the url in the way we are used to, without
34 : /// the #. However note that you will need to configure your server to make this work.
35 : /// Follow the instructions here: [https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations]
36 : final VRouterModes mode;
37 :
38 0 : @override
39 : Future<void> beforeEnter(VRedirector vRedirector) =>
40 0 : _beforeEnter(vRedirector);
41 : final Future<void> Function(VRedirector vRedirector) _beforeEnter;
42 :
43 0 : @override
44 : Future<void> beforeLeave(
45 : VRedirector vRedirector,
46 : void Function(Map<String, String> historyState) saveHistoryState,
47 : ) =>
48 0 : _beforeLeave(vRedirector, saveHistoryState);
49 : final Future<void> Function(
50 : VRedirector vRedirector,
51 : void Function(Map<String, String> historyState) saveHistoryState,
52 : ) _beforeLeave;
53 :
54 0 : @override
55 : void afterEnter(BuildContext context, String? from, String to) =>
56 0 : _afterEnter(context, from, to);
57 : final void Function(BuildContext context, String? from, String to)
58 : _afterEnter;
59 :
60 0 : @override
61 0 : Future<void> onPop(VRedirector vRedirector) => _onPop(vRedirector);
62 : final Future<void> Function(VRedirector vRedirector) _onPop;
63 :
64 0 : @override
65 : Future<void> onSystemPop(VRedirector vRedirector) =>
66 0 : _onSystemPop(vRedirector);
67 : final Future<void> Function(VRedirector vRedirector) _onSystemPop;
68 :
69 : /// This allows you to change the initial url
70 : ///
71 : /// The default is '/'
72 : final String initialUrl;
73 :
74 0 : WidgetsVRouter({
75 : Key? key,
76 : required this.routes,
77 : Future<void> Function(VRedirector vRedirector) beforeEnter =
78 : VGuard._voidBeforeEnter,
79 : Future<void> Function(
80 : VRedirector vRedirector,
81 : void Function(Map<String, String> historyState) saveHistoryState,
82 : )
83 : beforeLeave = VGuard._voidBeforeLeave,
84 : void Function(BuildContext context, String? from, String to) afterEnter =
85 : VGuard._voidAfterEnter,
86 : Future<void> Function(VRedirector vRedirector) onPop =
87 : VPopHandler._voidOnPop,
88 : Future<void> Function(VRedirector vRedirector) onSystemPop =
89 : VPopHandler._voidOnSystemPop,
90 : this.buildTransition,
91 : this.transitionDuration,
92 : this.reverseTransitionDuration,
93 : this.mode = VRouterModes.hash,
94 : this.initialUrl = '/',
95 : this.navigatorObservers = const [],
96 : this.builder,
97 : // Bellow are the WidgetsApp parameters
98 : this.title = '',
99 : this.onGenerateTitle,
100 : this.textStyle,
101 : required this.color,
102 : this.locale,
103 : this.localizationsDelegates,
104 : this.localeListResolutionCallback,
105 : this.localeResolutionCallback,
106 : this.supportedLocales = const <Locale>[Locale('en', 'US')],
107 : this.showPerformanceOverlay = false,
108 : this.checkerboardRasterCacheImages = false,
109 : this.checkerboardOffscreenLayers = false,
110 : this.showSemanticsDebugger = false,
111 : this.debugShowWidgetInspector = false,
112 : this.debugShowCheckedModeBanner = true,
113 : this.inspectorSelectButtonBuilder,
114 : this.shortcuts,
115 : this.actions,
116 : this.restorationScopeId,
117 : }) : _beforeEnter = beforeEnter,
118 : _beforeLeave = beforeLeave,
119 : _afterEnter = afterEnter,
120 : _onPop = onPop,
121 : _onSystemPop = onSystemPop,
122 0 : super(key: key);
123 :
124 0 : @override
125 0 : WidgetsVRouterState createState() => WidgetsVRouterState();
126 :
127 : /// {@macro flutter.widgets.widgetsApp.navigatorObservers}
128 : final List<NavigatorObserver> navigatorObservers;
129 :
130 : /// {@macro flutter.widgets.widgetsApp.builder}
131 : ///
132 : /// Material specific features such as [showDialog] and [showMenu], and widgets
133 : /// such as [Tooltip], [PopupMenuButton], also require a [Navigator] to properly
134 : /// function.
135 : final TransitionBuilder? builder;
136 :
137 : /// {@macro flutter.widgets.widgetsApp.title}
138 : ///
139 : /// This value is passed unmodified to [WidgetsApp.title].
140 : final String title;
141 :
142 : /// {@macro flutter.widgets.widgetsApp.onGenerateTitle}
143 : ///
144 : /// This value is passed unmodified to [WidgetsApp.onGenerateTitle].
145 : final GenerateAppTitle? onGenerateTitle;
146 :
147 : /// The default text style for [Text] in the application.
148 : final TextStyle? textStyle;
149 :
150 : /// {@template flutter.widgets.widgetsApp.color}
151 : /// The primary color to use for the application in the operating system
152 : /// interface.
153 : ///
154 : /// For example, on Android this is the color used for the application in the
155 : /// application switcher.
156 : /// {@endtemplate}
157 : final Color color;
158 :
159 : /// {@template flutter.widgets.widgetsApp.locale}
160 : /// The initial locale for this app's [Localizations] widget is based
161 : /// on this value.
162 : ///
163 : /// If the 'locale' is null then the system's locale value is used.
164 : ///
165 : /// The value of [Localizations.locale] will equal this locale if
166 : /// it matches one of the [supportedLocales]. Otherwise it will be
167 : /// the first element of [supportedLocales].
168 : /// {@endtemplate}
169 : ///
170 : /// See also:
171 : ///
172 : /// * [localeResolutionCallback], which can override the default
173 : /// [supportedLocales] matching algorithm.
174 : /// * [localizationsDelegates], which collectively define all of the localized
175 : /// resources used by this app.
176 : final Locale? locale;
177 :
178 : /// {@macro flutter.widgets.widgetsApp.localizationsDelegates}
179 : ///
180 : /// Internationalized apps that require translations for one of the locales
181 : /// listed in [GlobalMaterialLocalizations] should specify this parameter
182 : /// and list the [supportedLocales] that the application can handle.
183 : ///
184 : /// ```dart
185 : /// import 'package:flutter_localizations/flutter_localizations.dart';
186 : /// MaterialApp(
187 : /// localizationsDelegates: [
188 : /// // ... app-specific localization delegate[s] here
189 : /// GlobalMaterialLocalizations.delegate,
190 : /// GlobalWidgetsLocalizations.delegate,
191 : /// ],
192 : /// supportedLocales: [
193 : /// const Locale('en', 'US'), // English
194 : /// const Locale('he', 'IL'), // Hebrew
195 : /// // ... other locales the app supports
196 : /// ],
197 : /// // ...
198 : /// )
199 : /// ```
200 : ///
201 : /// ## Adding localizations for a new locale
202 : ///
203 : /// The information that follows applies to the unusual case of an app
204 : /// adding translations for a language not already supported by
205 : /// [GlobalMaterialLocalizations].
206 : ///
207 : /// Delegates that produce [WidgetsLocalizations] and [MaterialLocalizations]
208 : /// are included automatically. Apps can provide their own versions of these
209 : /// localizations by creating implementations of
210 : /// [LocalizationsDelegate<WidgetsLocalizations>] or
211 : /// [LocalizationsDelegate<MaterialLocalizations>] whose load methods return
212 : /// custom versions of [WidgetsLocalizations] or [MaterialLocalizations].
213 : ///
214 : /// For example: to add support to [MaterialLocalizations] for a
215 : /// locale it doesn't already support, say `const Locale('foo', 'BR')`,
216 : /// one could just extend [DefaultMaterialLocalizations]:
217 : ///
218 : /// ```dart
219 : /// class FooLocalizations extends DefaultMaterialLocalizations {
220 : /// FooLocalizations(Locale locale) : super(locale);
221 : /// @override
222 : /// String get okButtonLabel {
223 : /// if (locale == const Locale('foo', 'BR'))
224 : /// return 'foo';
225 : /// return super.okButtonLabel;
226 : /// }
227 : /// }
228 : ///
229 : /// ```
230 : ///
231 : /// A `FooLocalizationsDelegate` is essentially just a method that constructs
232 : /// a `FooLocalizations` object. We return a [SynchronousFuture] here because
233 : /// no asynchronous work takes place upon "loading" the localizations object.
234 : ///
235 : /// ```dart
236 : /// class FooLocalizationsDelegate extends LocalizationsDelegate<MaterialLocalizations> {
237 : /// const FooLocalizationsDelegate();
238 : /// @override
239 : /// Future<FooLocalizations> load(Locale locale) {
240 : /// return SynchronousFuture(FooLocalizations(locale));
241 : /// }
242 : /// @override
243 : /// bool shouldReload(FooLocalizationsDelegate old) => false;
244 : /// }
245 : /// ```
246 : ///
247 : /// Constructing a [MaterialApp] with a `FooLocalizationsDelegate` overrides
248 : /// the automatically included delegate for [MaterialLocalizations] because
249 : /// only the first delegate of each [LocalizationsDelegate.type] is used and
250 : /// the automatically included delegates are added to the end of the app's
251 : /// [localizationsDelegates] list.
252 : ///
253 : /// ```dart
254 : /// MaterialApp(
255 : /// localizationsDelegates: [
256 : /// const FooLocalizationsDelegate(),
257 : /// ],
258 : /// // ...
259 : /// )
260 : /// ```
261 : /// See also:
262 : ///
263 : /// * [supportedLocales], which must be specified along with
264 : /// [localizationsDelegates].
265 : /// * [GlobalMaterialLocalizations], a [localizationsDelegates] value
266 : /// which provides material localizations for many languages.
267 : /// * The Flutter Internationalization Tutorial,
268 : /// <https://flutter.dev/tutorials/internationalization/>.
269 : final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates;
270 :
271 : /// {@macro flutter.widgets.widgetsApp.localeListResolutionCallback}
272 : ///
273 : /// This callback is passed along to the [WidgetsApp] built by this widget.
274 : final LocaleListResolutionCallback? localeListResolutionCallback;
275 :
276 : /// {@macro flutter.widgets.LocaleResolutionCallback}
277 : ///
278 : /// This callback is passed along to the [WidgetsApp] built by this widget.
279 : final LocaleResolutionCallback? localeResolutionCallback;
280 :
281 : /// {@macro flutter.widgets.widgetsApp.supportedLocales}
282 : ///
283 : /// It is passed along unmodified to the [WidgetsApp] built by this widget.
284 : ///
285 : /// See also:
286 : ///
287 : /// * [localizationsDelegates], which must be specified for localized
288 : /// applications.
289 : /// * [GlobalMaterialLocalizations], a [localizationsDelegates] value
290 : /// which provides material localizations for many languages.
291 : /// * The Flutter Internationalization Tutorial,
292 : /// <https://flutter.dev/tutorials/internationalization/>.
293 : final Iterable<Locale> supportedLocales;
294 :
295 : /// Turns on a performance overlay.
296 : ///
297 : /// See also:
298 : ///
299 : /// * <https://flutter.dev/debugging/#performanceoverlay>
300 : final bool showPerformanceOverlay;
301 :
302 : /// Turns on checkerboarding of raster cache images.
303 : final bool checkerboardRasterCacheImages;
304 :
305 : /// Turns on checkerboarding of layers rendered to offscreen bitmaps.
306 : final bool checkerboardOffscreenLayers;
307 :
308 : /// Turns on an overlay that shows the accessibility information
309 : /// reported by the framework.
310 : final bool showSemanticsDebugger;
311 :
312 : /// Turns on an overlay that enables inspecting the widget tree.
313 : ///
314 : /// The inspector is only available in checked mode as it depends on
315 : /// [RenderObject.debugDescribeChildren] which should not be called outside of
316 : /// checked mode.
317 : final bool debugShowWidgetInspector;
318 :
319 : /// {@template flutter.widgets.widgetsApp.debugShowCheckedModeBanner}
320 : /// Turns on a little "DEBUG" banner in checked mode to indicate
321 : /// that the app is in checked mode. This is on by default (in
322 : /// checked mode), to turn it off, set the constructor argument to
323 : /// false. In release mode this has no effect.
324 : ///
325 : /// To get this banner in your application if you're not using
326 : /// WidgetsApp, include a [CheckedModeBanner] widget in your app.
327 : ///
328 : /// This banner is intended to deter people from complaining that your
329 : /// app is slow when it's in checked mode. In checked mode, Flutter
330 : /// enables a large number of expensive diagnostics to aid in
331 : /// development, and so performance in checked mode is not
332 : /// representative of what will happen in release mode.
333 : /// {@endtemplate}
334 : final bool debugShowCheckedModeBanner;
335 :
336 : /// Builds the widget the [WidgetInspector] uses to switch between view and
337 : /// inspect modes.
338 : ///
339 : /// This lets [MaterialApp] to use a material button to toggle the inspector
340 : /// select mode without requiring [WidgetInspector] to depend on the
341 : /// material package.
342 : final InspectorSelectButtonBuilder? inspectorSelectButtonBuilder;
343 :
344 : /// {@macro flutter.widgets.widgetsApp.shortcuts}
345 : /// {@tool snippet}
346 : /// This example shows how to add a single shortcut for
347 : /// [LogicalKeyboardKey.select] to the default shortcuts without needing to
348 : /// add your own [Shortcuts] widget.
349 : ///
350 : /// Alternatively, you could insert a [Shortcuts] widget with just the mapping
351 : /// you want to add between the [WidgetsApp] and its child and get the same
352 : /// effect.
353 : ///
354 : /// ```dart
355 : /// Widget build(BuildContext context) {
356 : /// return WidgetsApp(
357 : /// shortcuts: <LogicalKeySet, Intent>{
358 : /// ... WidgetsApp.defaultShortcuts,
359 : /// LogicalKeySet(LogicalKeyboardKey.select): const ActivateIntent(),
360 : /// },
361 : /// color: const Color(0xFFFF0000),
362 : /// builder: (BuildContext context, Widget child) {
363 : /// return const Placeholder();
364 : /// },
365 : /// );
366 : /// }
367 : /// ```
368 : /// {@end-tool}
369 : /// {@macro flutter.widgets.widgetsApp.shortcuts.seeAlso}
370 : final Map<LogicalKeySet, Intent>? shortcuts;
371 :
372 : /// {@macro flutter.widgets.widgetsApp.actions}
373 : /// {@tool snippet}
374 : /// This example shows how to add a single action handling an
375 : /// [ActivateAction] to the default actions without needing to
376 : /// add your own [Actions] widget.
377 : ///
378 : /// Alternatively, you could insert a [Actions] widget with just the mapping
379 : /// you want to add between the [WidgetsApp] and its child and get the same
380 : /// effect.
381 : ///
382 : /// ```dart
383 : /// Widget build(BuildContext context) {
384 : /// return WidgetsApp(
385 : /// actions: <Type, Action<Intent>>{
386 : /// ... WidgetsApp.defaultActions,
387 : /// ActivateAction: CallbackAction(
388 : /// onInvoke: (Intent intent) {
389 : /// // Do something here...
390 : /// return null;
391 : /// },
392 : /// ),
393 : /// },
394 : /// color: const Color(0xFFFF0000),
395 : /// builder: (BuildContext context, Widget child) {
396 : /// return const Placeholder();
397 : /// },
398 : /// );
399 : /// }
400 : /// ```
401 : /// {@end-tool}
402 : /// {@macro flutter.widgets.widgetsApp.actions.seeAlso}
403 : final Map<Type, Action<Intent>>? actions;
404 :
405 : /// {@template flutter.widgets.widgetsApp.restorationScopeId}
406 : /// The identifier to use for state restoration of this app.
407 : ///
408 : /// Providing a restoration ID inserts a [RootRestorationScope] into the
409 : /// widget hierarchy, which enables state restoration for descendant widgets.
410 : ///
411 : /// Providing a restoration ID also enables the [Navigator] built by the
412 : /// [WidgetsApp] to restore its state (i.e. to restore the history stack of
413 : /// active [Route]s). See the documentation on [Navigator] for more details
414 : /// around state restoration of [Route]s.
415 : ///
416 : /// See also:
417 : ///
418 : /// * [RestorationManager], which explains how state restoration works in
419 : /// Flutter.
420 : /// {@endtemplate}
421 : final String? restorationScopeId;
422 :
423 0 : static VRouterData of(BuildContext context) {
424 : VRouterData? vRouterData;
425 :
426 : // First try to get a local MaterialVRouterData
427 : vRouterData =
428 0 : context.dependOnInheritedWidgetOfExactType<LocalVRouterData>();
429 : if (vRouterData != null) {
430 : return vRouterData;
431 : }
432 :
433 : // Else try to get the root MaterialVRouterData
434 0 : vRouterData = context.dependOnInheritedWidgetOfExactType<RootVRouterData>();
435 : if (vRouterData != null) {
436 : return vRouterData;
437 : }
438 :
439 : if (vRouterData == null) {
440 0 : throw FlutterError(
441 : 'MaterialVRouter.of(context) was called with a context which does not contain a MaterialVRouter.\n'
442 : 'The context used to retrieve MaterialVRouter must be that of a widget that '
443 : 'is a descendant of a MaterialVRouter widget.');
444 : }
445 : return vRouterData;
446 : }
447 :
448 0 : @override
449 0 : List<VRouteElement> buildRoutes() => routes;
450 :
451 0 : @override
452 : void afterUpdate(BuildContext context, String? from, String to) {}
453 :
454 : @override
455 0 : Future<void> beforeUpdate(VRedirector vRedirector) async {}
456 : }
457 :
458 : class WidgetsVRouterState extends State<WidgetsVRouter> {
459 : late final vRouterDelegate = VRouterDelegate(
460 : routes: widget.routes,
461 : builder: widget.builder,
462 : navigatorObservers: widget.navigatorObservers,
463 : beforeEnter: widget.beforeEnter,
464 : beforeLeave: widget.beforeLeave,
465 : afterEnter: widget.afterEnter,
466 : onPop: widget.onPop,
467 : onSystemPop: widget.onSystemPop,
468 : buildTransition: widget.buildTransition,
469 : transitionDuration: widget.transitionDuration,
470 : reverseTransitionDuration: widget.reverseTransitionDuration,
471 : mode: widget.mode,
472 : initialUrl: widget.initialUrl,
473 : );
474 :
475 0 : @override
476 : Widget build(BuildContext context) {
477 0 : return WidgetsApp.router(
478 0 : backButtonDispatcher: VBackButtonDispatcher(),
479 0 : routeInformationParser: VRouteInformationParser(),
480 0 : routerDelegate: vRouterDelegate,
481 0 : title: widget.title,
482 0 : onGenerateTitle: widget.onGenerateTitle,
483 0 : textStyle: widget.textStyle,
484 0 : color: widget.color,
485 0 : locale: widget.locale,
486 0 : localizationsDelegates: widget.localizationsDelegates,
487 0 : localeListResolutionCallback: widget.localeListResolutionCallback,
488 0 : localeResolutionCallback: widget.localeResolutionCallback,
489 0 : supportedLocales: widget.supportedLocales,
490 0 : showPerformanceOverlay: widget.showPerformanceOverlay,
491 0 : checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
492 0 : checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
493 0 : showSemanticsDebugger: widget.showSemanticsDebugger,
494 0 : debugShowWidgetInspector: widget.debugShowWidgetInspector,
495 0 : debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner,
496 0 : inspectorSelectButtonBuilder: widget.inspectorSelectButtonBuilder,
497 0 : shortcuts: widget.shortcuts,
498 0 : actions: widget.actions,
499 0 : restorationScopeId: widget.restorationScopeId,
500 : );
501 : }
502 :
503 : /// Url currently synced with the state
504 : /// This url can differ from the once of the browser if
505 : /// the state has been yet been updated
506 0 : String? get url => vRouterDelegate.url;
507 :
508 : /// Previous url that was synced with the state
509 0 : String? get previousUrl => vRouterDelegate.previousUrl;
510 :
511 : /// This state is saved in the browser history. This means that if the user presses
512 : /// the back or forward button on the navigator, this historyState will be the same
513 : /// as the last one you saved.
514 : ///
515 : /// It can be changed by using [context.vRouter.replaceHistoryState(newState)]
516 0 : Map<String, String> get historyState => vRouterDelegate.historyState;
517 :
518 : /// Maps all route parameters (i.e. parameters of the path
519 : /// mentioned as ":someId")
520 0 : Map<String, String> get pathParameters => vRouterDelegate.pathParameters;
521 :
522 : /// Contains all query parameters (i.e. parameters after
523 : /// the "?" in the url) of the current url
524 0 : Map<String, String> get queryParameters => vRouterDelegate.queryParameters;
525 :
526 : /// Starts a pop cycle
527 : ///
528 : /// Pop cycle:
529 : /// 1. onPop is called in all [VNavigationGuard]s
530 : /// 2. onPop is called in all [VRouteElement]s of the current route
531 : /// 3. onPop is called in [VRouter]
532 : ///
533 : /// In any of the above steps, we can use [vRedirector] if you want to redirect or
534 : /// stop the navigation
535 0 : Future<void> pop({
536 : Map<String, String> pathParameters = const {},
537 : Map<String, String> queryParameters = const {},
538 : Map<String, String> newHistoryState = const {},
539 : }) async =>
540 0 : vRouterDelegate.pop(
541 : pathParameters: pathParameters,
542 : queryParameters: queryParameters,
543 : newHistoryState: newHistoryState,
544 : );
545 :
546 : /// Starts a systemPop cycle
547 : ///
548 : /// systemPop cycle:
549 : /// 1. onSystemPop (or onPop if not implemented) is called in all VNavigationGuards
550 : /// 2. onSystemPop (or onPop if not implemented) is called in the nested-most VRouteElement of the current route
551 : /// 3. onSystemPop (or onPop if not implemented) is called in MaterialVRouter
552 : ///
553 : /// In any of the above steps, we can use a [VRedirector] if you want to redirect or
554 : /// stop the navigation
555 0 : Future<void> systemPop({
556 : Map<String, String> pathParameters = const {},
557 : Map<String, String> queryParameters = const {},
558 : Map<String, String> newHistoryState = const {},
559 : }) async =>
560 0 : vRouterDelegate.systemPop(
561 : pathParameters: pathParameters,
562 : queryParameters: queryParameters,
563 : newHistoryState: newHistoryState,
564 : );
565 :
566 : /// Pushes the new route of the given url on top of the current one
567 : /// A path can be of one of two forms:
568 : /// * stating with '/', in which case we just navigate
569 : /// to the given path
570 : /// * not starting with '/', in which case we append the
571 : /// current path to the given one
572 : ///
573 : /// We can also specify queryParameters, either by directly
574 : /// putting them is the url or by providing a Map using [queryParameters]
575 : ///
576 : /// We can also put a state to the next route, this state will
577 : /// be a router state (this is the only kind of state that we can
578 : /// push) accessible with MaterialVRouter.of(context).historyState
579 0 : void push(
580 : String newUrl, {
581 : Map<String, String> queryParameters = const {},
582 : Map<String, String> historyState = const {},
583 : }) =>
584 0 : vRouterDelegate.push(
585 : newUrl,
586 : queryParameters: queryParameters,
587 : historyState: historyState,
588 : );
589 :
590 : /// Updates the url given a [VRouteElement] name
591 : ///
592 : /// We can also specify path parameters to inject into the new path
593 : ///
594 : /// We can also specify queryParameters, either by directly
595 : /// putting them is the url or by providing a Map using [queryParameters]
596 : ///
597 : /// We can also put a state to the next route, this state will
598 : /// be a router state (this is the only kind of state that we can
599 : /// push) accessible with MaterialVRouter.of(context).historyState
600 : ///
601 : /// After finding the url and taking charge of the path parameters,
602 : /// it updates the url
603 : ///
604 : /// To specify a name, see [VRouteElement.name]
605 0 : void pushNamed(
606 : String name, {
607 : Map<String, String> pathParameters = const {},
608 : Map<String, String> queryParameters = const {},
609 : Map<String, String> historyState = const {},
610 : }) =>
611 0 : vRouterDelegate.pushNamed(
612 : name,
613 : pathParameters: pathParameters,
614 : queryParameters: queryParameters,
615 : historyState: historyState,
616 : );
617 :
618 : /// Replace the current one by the new route corresponding to the given url
619 : /// The difference with [push] is that this overwrites the current browser history entry
620 : /// If you are on mobile, this is the same as push
621 : /// Path can be of one of two forms:
622 : /// * stating with '/', in which case we just navigate
623 : /// to the given path
624 : /// * not starting with '/', in which case we append the
625 : /// current path to the given one
626 : ///
627 : /// We can also specify queryParameters, either by directly
628 : /// putting them is the url or by providing a Map using [queryParameters]
629 : ///
630 : /// We can also put a state to the next route, this state will
631 : /// be a router state (this is the only kind of state that we can
632 : /// push) accessible with MaterialVRouter.of(context).historyState
633 0 : void pushReplacement(
634 : String newUrl, {
635 : Map<String, String> queryParameters = const {},
636 : Map<String, String> historyState = const {},
637 : }) =>
638 0 : vRouterDelegate.pushReplacement(
639 : newUrl,
640 : queryParameters: queryParameters,
641 : historyState: historyState,
642 : );
643 :
644 : /// Replace the url given a [VRouteElement] name
645 : /// The difference with [pushNamed] is that this overwrites the current browser history entry
646 : ///
647 : /// We can also specify path parameters to inject into the new path
648 : ///
649 : /// We can also specify queryParameters, either by directly
650 : /// putting them is the url or by providing a Map using [queryParameters]
651 : ///
652 : /// We can also put a state to the next route, this state will
653 : /// be a router state (this is the only kind of state that we can
654 : /// push) accessible with MaterialVRouter.of(context).historyState
655 : ///
656 : /// After finding the url and taking charge of the path parameters
657 : /// it updates the url
658 : ///
659 : /// To specify a name, see [VPath.name]
660 0 : void pushReplacementNamed(
661 : String name, {
662 : Map<String, String> pathParameters = const {},
663 : Map<String, String> queryParameters = const {},
664 : Map<String, String> historyState = const {},
665 : }) =>
666 0 : vRouterDelegate.pushReplacementNamed(
667 : name,
668 : pathParameters: pathParameters,
669 : queryParameters: queryParameters,
670 : historyState: historyState,
671 : );
672 :
673 : /// Goes to an url which is not in the app
674 : ///
675 : /// On the web, you can set [openNewTab] to true to open this url
676 : /// in a new tab
677 0 : void pushExternal(String newUrl, {bool openNewTab = false}) =>
678 0 : vRouterDelegate.pushExternal(
679 : newUrl,
680 : openNewTab: openNewTab,
681 : );
682 : }
|