Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
fluttertpc_get
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Ahmed Fwela
2021-07-21 06:33:18 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
54e5ffec6782ad8d7a08480957bcb3faa53ca659
54e5ffec
1 parent
9c9f7144
- Improved router delegate
- Rolled back RouterOutlet, and introduced simpler API
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
123 additions
and
131 deletions
example_nav2/lib/app/middleware/auth_middleware.dart
example_nav2/lib/app/modules/home/views/home_view.dart
example_nav2/lib/app/modules/profile/controllers/profile_controller.dart
example_nav2/lib/app/modules/root/views/root_view.dart
example_nav2/lib/app/routes/app_pages.dart
lib/get_navigation/src/nav2/get_router_delegate.dart
lib/get_navigation/src/nav2/router_outlet.dart
lib/get_navigation/src/routes/route_middleware.dart
example_nav2/lib/app/middleware/auth_middleware.dart
View file @
54e5ffe
...
...
@@ -5,18 +5,22 @@ import '../routes/app_pages.dart';
class
EnsureAuthMiddleware
extends
GetMiddleware
{
@override
GetNavConfig
?
redirectDelegate
(
GetNavConfig
route
)
{
Future
<
GetNavConfig
?>
redirectDelegate
(
GetNavConfig
route
)
async
{
// you can do whatever you want here
// but it's preferable to make this method fast
// await Future.delayed(Duration(milliseconds: 500));
if
(!
AuthService
.
to
.
isLoggedInValue
)
{
final
newRoute
=
Routes
.
LOGIN_THEN
(
route
.
location
!);
return
GetNavConfig
.
fromRoute
(
newRoute
);
}
return
super
.
redirectDelegate
(
route
);
return
await
super
.
redirectDelegate
(
route
);
}
}
class
EnsureNotAuthedMiddleware
extends
GetMiddleware
{
@override
GetNavConfig
?
redirectDelegate
(
GetNavConfig
route
)
{
Future
<
GetNavConfig
?>
redirectDelegate
(
GetNavConfig
route
)
async
{
if
(
AuthService
.
to
.
isLoggedInValue
)
{
//NEVER navigate to auth screen, when user is already authed
return
null
;
...
...
@@ -24,6 +28,6 @@ class EnsureNotAuthedMiddleware extends GetMiddleware {
//OR redirect user to another screen
//return GetNavConfig.fromRoute(Routes.PROFILE);
}
return
super
.
redirectDelegate
(
route
);
return
await
super
.
redirectDelegate
(
route
);
}
}
...
...
example_nav2/lib/app/modules/home/views/home_view.dart
View file @
54e5ffe
...
...
@@ -19,8 +19,10 @@ class HomeView extends GetView<HomeController> {
currentIndex
=
1
;
}
return
Scaffold
(
body:
GetRouterOutlet
(
body:
GetRouterOutlet
.
fromRoute
(
initialRoute:
Routes
.
DASHBOARD
,
anchorRoute:
Routes
.
HOME
,
key:
Get
.
nestedKey
(
Routes
.
HOME
),
),
bottomNavigationBar:
BottomNavigationBar
(
currentIndex:
currentIndex
,
...
...
example_nav2/lib/app/modules/profile/controllers/profile_controller.dart
View file @
54e5ffe
import
'package:get/get.dart'
;
class
ProfileController
extends
GetxController
{
//TODO: Implement ProfileController
final
count
=
0
.
obs
;
@override
void
onInit
()
{
super
.
onInit
();
}
@override
void
onReady
()
{
super
.
onReady
();
}
@override
void
onClose
()
{}
void
increment
()
=>
count
.
value
++;
}
class
ProfileController
extends
GetxController
{}
...
...
example_nav2/lib/app/modules/root/views/root_view.dart
View file @
54e5ffe
...
...
@@ -17,8 +17,12 @@ class RootView extends GetView<RootController> {
title:
Text
(
title
??
''
),
centerTitle:
true
,
),
body:
GetRouterOutlet
(
body:
GetRouterOutlet
.
fromRoute
(
initialRoute:
Routes
.
HOME
,
anchorRoute:
'/'
,
filterPages:
(
afterAnchor
)
{
return
afterAnchor
.
take
(
1
);
},
),
);
},
...
...
example_nav2/lib/app/routes/app_pages.dart
View file @
54e5ffe
...
...
@@ -43,7 +43,6 @@ class AppPages {
binding:
LoginBinding
(),
),
GetPage
(
participatesInRootNavigator:
false
,
preventDuplicates:
true
,
name:
_Paths
.
HOME
,
page:
()
=>
HomeView
(),
...
...
lib/get_navigation/src/nav2/get_router_delegate.dart
View file @
54e5ffe
...
...
@@ -52,56 +52,61 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
final
PopMode
backButtonPopMode
;
final
PreventDuplicateHandlingMode
preventDuplicateHandlingMode
;
GetPage
?
notFoundRoute
;
final
GetPage
notFoundRoute
;
final
List
<
NavigatorObserver
>?
navigatorObservers
;
final
TransitionDelegate
<
dynamic
>?
transitionDelegate
;
final
_resultCompleter
=
<
GetNavConfig
,
Completer
<
Object
?>>{};
GlobalKey
<
NavigatorState
>
get
navigatorKey
=>
GetNavigation
.
getxController
.
key
;
GetDelegate
({
this
.
notFoundRoute
,
GetPage
?
notFoundRoute
,
this
.
navigatorObservers
,
this
.
transitionDelegate
,
this
.
backButtonPopMode
=
PopMode
.
History
,
this
.
preventDuplicateHandlingMode
=
PreventDuplicateHandlingMode
.
ReorderRoutes
,
})
{
})
:
notFoundRoute
=
notFoundRoute
??
GetPage
(
name:
'/404'
,
page:
()
=>
Scaffold
(
body:
Text
(
'Route not found'
),
),
)
{
Get
.
log
(
'GetDelegate is created !'
);
}
GetNavConfig
?
runMiddleware
(
GetNavConfig
config
)
{
Future
<
GetNavConfig
?>
runMiddleware
(
GetNavConfig
config
)
async
{
final
middlewares
=
config
.
currentTreeBranch
.
last
.
middlewares
;
if
(
middlewares
==
null
)
{
return
config
;
}
var
iterator
=
config
;
for
(
var
item
in
middlewares
)
{
var
redirectRes
=
item
.
redirectDelegate
(
iterator
);
var
redirectRes
=
await
item
.
redirectDelegate
(
iterator
);
if
(
redirectRes
==
null
)
return
null
;
iterator
=
redirectRes
;
}
return
iterator
;
}
void
_unsafeHistoryAdd
(
GetNavConfig
config
)
{
final
res
=
runMiddleware
(
config
);
Future
<
void
>
_unsafeHistoryAdd
(
GetNavConfig
config
)
async
{
final
res
=
await
runMiddleware
(
config
);
if
(
res
==
null
)
return
;
history
.
add
(
res
);
}
void
_unsafeHistoryRemove
(
GetNavConfig
config
)
{
Future
<
void
>
_unsafeHistoryRemove
(
GetNavConfig
config
)
async
{
var
index
=
history
.
indexOf
(
config
);
if
(
index
>=
0
)
_unsafeHistoryRemoveAt
(
index
);
if
(
index
>=
0
)
await
_unsafeHistoryRemoveAt
(
index
);
}
GetNavConfig
?
_unsafeHistoryRemoveAt
(
int
index
)
{
Future
<
GetNavConfig
?>
_unsafeHistoryRemoveAt
(
int
index
)
async
{
if
(
index
==
history
.
length
-
1
&&
history
.
length
>
1
)
{
//removing WILL update the current route
final
toCheck
=
history
[
history
.
length
-
2
];
final
resMiddleware
=
runMiddleware
(
toCheck
);
final
resMiddleware
=
await
runMiddleware
(
toCheck
);
if
(
resMiddleware
==
null
)
return
null
;
history
[
history
.
length
-
2
]
=
resMiddleware
;
}
...
...
@@ -113,38 +118,33 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
// }
/// Adds a new history entry and waits for the result
Future
<
T
?>
pushHistory
<
T
>
(
Future
<
void
>
pushHistory
(
GetNavConfig
config
,
{
bool
rebuildStack
=
true
,
})
{
})
async
{
//this changes the currentConfiguration
final
completer
=
Completer
<
T
?>();
_resultCompleter
[
config
]
=
completer
;
_pushHistory
(
config
);
await
_pushHistory
(
config
);
if
(
rebuildStack
)
{
refresh
();
}
return
completer
.
future
;
}
void
_removeHistoryEntry
(
GetNavConfig
entry
)
{
_unsafeHistoryRemove
(
entry
);
final
lastCompleter
=
_resultCompleter
.
remove
(
entry
);
lastCompleter
?.
complete
(
entry
);
Future
<
void
>
_removeHistoryEntry
(
GetNavConfig
entry
)
async
{
await
_unsafeHistoryRemove
(
entry
);
}
void
_pushHistory
(
GetNavConfig
config
)
{
Future
<
void
>
_pushHistory
(
GetNavConfig
config
)
async
{
if
(
config
.
currentPage
!.
preventDuplicates
)
{
final
originalEntryIndex
=
history
.
indexWhere
((
element
)
=>
element
.
location
==
config
.
location
);
if
(
originalEntryIndex
>=
0
)
{
switch
(
preventDuplicateHandlingMode
)
{
case
PreventDuplicateHandlingMode
.
PopUntilOriginalRoute
:
until
(
config
.
location
!,
popMode:
PopMode
.
Page
);
await
until
(
config
.
location
!,
popMode:
PopMode
.
Page
);
break
;
case
PreventDuplicateHandlingMode
.
ReorderRoutes
:
_unsafeHistoryRemoveAt
(
originalEntryIndex
);
_unsafeHistoryAdd
(
config
);
await
_unsafeHistoryRemoveAt
(
originalEntryIndex
);
await
_unsafeHistoryAdd
(
config
);
break
;
case
PreventDuplicateHandlingMode
.
DoNothing
:
default
:
...
...
@@ -153,7 +153,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
return
;
}
}
_unsafeHistoryAdd
(
config
);
await
_unsafeHistoryAdd
(
config
);
}
// GetPageRoute getPageRoute(RouteSettings? settings) {
...
...
@@ -161,33 +161,33 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
// .page();
// }
GetNavConfig
?
_popHistory
()
{
Future
<
GetNavConfig
?>
_popHistory
()
async
{
if
(!
_canPopHistory
())
return
null
;
return
_doPopHistory
();
return
await
_doPopHistory
();
}
GetNavConfig
?
_doPopHistory
()
{
return
_unsafeHistoryRemoveAt
(
history
.
length
-
1
);
Future
<
GetNavConfig
?>
_doPopHistory
()
async
{
return
await
_unsafeHistoryRemoveAt
(
history
.
length
-
1
);
}
GetNavConfig
?
_popPage
()
{
Future
<
GetNavConfig
?>
_popPage
()
async
{
if
(!
_canPopPage
())
return
null
;
return
_doPopPage
();
return
await
_doPopPage
();
}
GetNavConfig
?
_pop
(
PopMode
mode
)
{
Future
<
GetNavConfig
?>
_pop
(
PopMode
mode
)
async
{
switch
(
mode
)
{
case
PopMode
.
History
:
return
_popHistory
();
return
await
_popHistory
();
case
PopMode
.
Page
:
return
_popPage
();
return
await
_popPage
();
default
:
return
null
;
}
}
// returns the popped page
GetNavConfig
?
_doPopPage
()
{
Future
<
GetNavConfig
?>
_doPopPage
()
async
{
final
currentBranch
=
currentConfiguration
?.
currentTreeBranch
;
if
(
currentBranch
!=
null
&&
currentBranch
.
length
>
1
)
{
//remove last part only
...
...
@@ -202,13 +202,13 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
final
prevLocation
=
prevHistoryEntry
.
location
;
if
(
newLocation
==
prevLocation
)
{
//pop the entire history entry
return
_popHistory
();
return
await
_popHistory
();
}
}
//create a new route with the remaining tree branch
final
res
=
_popHistory
();
_pushHistory
(
final
res
=
await
_popHistory
();
await
_pushHistory
(
GetNavConfig
(
currentTreeBranch:
remaining
.
toList
(),
location:
remaining
.
last
.
name
,
...
...
@@ -218,12 +218,12 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
return
res
;
}
else
{
//remove entire entry
return
_popHistory
();
return
await
_popHistory
();
}
}
Future
<
GetNavConfig
?>
popHistory
()
{
return
SynchronousFuture
(
_popHistory
());
Future
<
GetNavConfig
?>
popHistory
()
async
{
return
await
_popHistory
();
}
bool
_canPopHistory
()
{
...
...
@@ -256,8 +256,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
/// gets the visual pages from the current history entry
///
/// visual pages must have the [RouterOutletContainerMiddleWare] middleware
/// with `stayAt` equal to the route name of the visual page
/// visual pages must have [participatesInRootNavigator] set to true
List
<
GetPage
>
getVisualPages
()
{
final
currentHistory
=
currentConfiguration
;
if
(
currentHistory
==
null
)
return
<
GetPage
>[];
...
...
@@ -278,6 +277,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
@override
Widget
build
(
BuildContext
context
)
{
final
pages
=
getVisualPages
();
if
(
pages
.
length
==
0
)
return
SizedBox
.
shrink
();
final
extraObservers
=
navigatorObservers
;
return
GetNavigator
(
key:
navigatorKey
,
...
...
@@ -292,13 +292,13 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
);
}
@override
Future
<
void
>
setInitialRoutePath
(
GetNavConfig
configuration
)
async
{
//no need to clear history with Reorder route strategy
// _unsafeHistoryClear();
// _resultCompleter.clear();
await
pushHistory
(
configuration
);
}
// @override
// Future<void> setInitialRoutePath(GetNavConfig configuration) async {
// //no need to clear history with Reorder route strategy
// // _unsafeHistoryClear();
// // _resultCompleter.clear();
// await pushHistory(configuration);
// }
@override
Future
<
void
>
setNewRoutePath
(
GetNavConfig
configuration
)
async
{
...
...
@@ -312,10 +312,10 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
return
route
;
}
Future
<
T
?>
toNamed
<
T
>(
String
fullRoute
)
{
Future
<
void
>
toNamed
(
String
fullRoute
)
async
{
final
decoder
=
Get
.
routeTree
.
matchRoute
(
fullRoute
);
return
pushHistory
<
T
>
(
return
await
pushHistory
(
GetNavConfig
(
currentTreeBranch:
decoder
.
treeBranch
,
location:
fullRoute
,
...
...
@@ -324,40 +324,31 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
);
}
Future
<
T
?>
offNamed
<
T
>
(
String
fullRoute
)
async
{
Future
<
void
>
offNamed
(
String
fullRoute
)
async
{
await
popHistory
();
return
await
toNamed
(
fullRoute
);
await
toNamed
(
fullRoute
);
}
/// Removes routes according to [PopMode]
/// until it reaches the specifc [fullRoute],
/// DOES NOT remove the [fullRoute]
void
until
(
Future
<
void
>
until
(
String
fullRoute
,
{
PopMode
popMode
=
PopMode
.
Page
,
})
{
})
async
{
// remove history or page entries until you meet route
var
iterator
=
currentConfiguration
;
while
(
_canPop
(
popMode
)
&&
iterator
!=
null
&&
iterator
.
location
!=
fullRoute
)
{
_pop
(
popMode
);
await
_pop
(
popMode
);
// replace iterator
iterator
=
currentConfiguration
;
}
refresh
();
}
// GetPage _notFound() {
// return notFoundRoute ??= GetPage(
// name: '/404',
// page: () => Scaffold(
// body: Text('not found'),
// ),
// );
// }
Future
<
bool
>
handlePopupRoutes
({
Object
?
result
,
})
async
{
...
...
@@ -380,15 +371,13 @@ class GetDelegate extends RouterDelegate<GetNavConfig>
//Returning false will cause the entire app to be popped.
final
wasPopup
=
await
handlePopupRoutes
(
result:
result
);
if
(
wasPopup
)
return
true
;
final
_popped
=
_pop
(
popMode
);
final
_popped
=
await
_pop
(
popMode
);
refresh
();
if
(
_popped
!=
null
)
{
//emulate the old pop with result
final
lastCompleter
=
_resultCompleter
.
remove
(
_popped
);
lastCompleter
?.
complete
(
result
);
return
Future
.
value
(
true
);
return
true
;
}
return
Future
.
value
(
false
)
;
return
false
;
}
bool
_onPopVisualRoute
(
Route
<
dynamic
>
route
,
dynamic
result
)
{
...
...
@@ -419,15 +408,9 @@ class GetNavigator extends Navigator {
List
<
NavigatorObserver
>?
observers
,
bool
reportsRouteUpdateToEngine
=
false
,
TransitionDelegate
?
transitionDelegate
,
// String? name,
})
:
super
(
//keys should be optional
key:
key
,
// key != null
// ? key
// : name != null
// ? Get.nestedKey(name)
// : null,
onPopPage:
onPopPage
??
(
route
,
result
)
{
final
didPop
=
route
.
didPop
(
result
);
...
...
lib/get_navigation/src/nav2/router_outlet.dart
View file @
54e5ffe
...
...
@@ -21,11 +21,11 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
RouterOutlet
({
TDelegate
?
delegate
,
required
List
<
GetPage
>
Function
(
T
currentNavStack
)
pickPages
,
required
Iterable
<
GetPage
>
Function
(
T
currentNavStack
)
pickPages
,
required
Widget
Function
(
BuildContext
context
,
TDelegate
,
List
<
GetPage
>?
page
,
Iterable
<
GetPage
>?
page
,
)
pageBuilder
,
})
:
this
.
builder
(
...
...
@@ -76,17 +76,38 @@ class _RouterOutletState<TDelegate extends RouterDelegate<T>, T extends Object>
}
class
GetRouterOutlet
extends
RouterOutlet
<
GetDelegate
,
GetNavConfig
>
{
GetRouterOutlet
({
GetRouterOutlet
.
fromRoute
({
required
String
anchorRoute
,
required
String
initialRoute
,
Iterable
<
GetPage
>
Function
(
Iterable
<
GetPage
>
afterAnchor
)?
filterPages
,
GlobalKey
<
NavigatorState
>?
key
,
})
:
this
(
pickPages:
(
config
)
{
var
ret
=
config
.
currentTreeBranch
.
pickAfterRoute
(
anchorRoute
);
if
(
filterPages
!=
null
)
{
ret
=
filterPages
(
ret
);
}
return
ret
;
},
emptyPage:
(
delegate
)
=>
Get
.
routeTree
.
matchRoute
(
initialRoute
).
route
??
delegate
.
notFoundRoute
,
key:
key
,
);
GetRouterOutlet
({
Widget
Function
(
GetDelegate
delegate
)?
emptyWidget
,
GetPage
Function
(
GetDelegate
delegate
)?
emptyPage
,
required
Iterable
<
GetPage
>
Function
(
GetNavConfig
currentNavStack
)
pickPages
,
bool
Function
(
Route
<
dynamic
>,
dynamic
)?
onPopPage
,
// String? name
,
GlobalKey
<
NavigatorState
>?
key
,
})
:
super
(
pageBuilder:
(
context
,
rDelegate
,
pages
)
{
final
route
=
Get
.
routeTree
.
matchRoute
(
initialRoute
);
final
pageRes
=
(
pages
??
<
GetPage
<
dynamic
>?>[
route
.
route
])
.
whereType
<
GetPage
<
dynamic
>>()
.
toList
();
final
pageRes
=
<
GetPage
?>[
...?
pages
,
if
(
pages
==
null
||
pages
.
length
==
0
)
emptyPage
?.
call
(
rDelegate
),
].
whereType
<
GetPage
>();
if
(
pageRes
.
length
>
0
)
{
return
GetNavigator
(
onPopPage:
onPopPage
??
...
...
@@ -97,19 +118,13 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> {
}
return
true
;
},
pages:
pageRes
,
//name: name,
pages:
pageRes
.
toList
(),
key:
key
,
);
}
return
(
emptyWidget
?.
call
(
rDelegate
)
??
SizedBox
.
shrink
());
},
pickPages:
(
currentNavStack
)
{
final
length
=
Uri
.
parse
(
initialRoute
).
pathSegments
.
length
;
return
currentNavStack
.
currentTreeBranch
.
skip
(
length
)
.
take
(
length
)
.
toList
();
},
pickPages:
pickPages
,
delegate:
Get
.
rootDelegate
,
);
...
...
@@ -127,12 +142,12 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> {
);
}
// extension PagesListExt on List<GetPage> {
// List<GetPage> pickAtRoute(String route) {
// return skipWhile((value) => value.name != route).toList();
// }
extension
PagesListExt
on
List
<
GetPage
>
{
Iterable
<
GetPage
>
pickAtRoute
(
String
route
)
{
return
skipWhile
((
value
)
=>
value
.
name
!=
route
).
toList
();
}
// List<GetPage> pickAfterRoute(String route) {
// return skipWhile((value) => value.name != route).skip(1).toList();
// }
// }
Iterable
<
GetPage
>
pickAfterRoute
(
String
route
)
{
return
skipWhile
((
value
)
=>
value
.
name
!=
route
).
skip
(
1
).
toList
();
}
}
...
...
lib/get_navigation/src/routes/route_middleware.dart
View file @
54e5ffe
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'../../../get.dart'
;
abstract
class
_RouteMiddleware
{
...
...
@@ -49,7 +50,7 @@ abstract class _RouteMiddleware {
/// }
/// ```
/// {@end-tool}
GetNavConfig
?
redirectDelegate
(
GetNavConfig
route
);
Future
<
GetNavConfig
?>
redirectDelegate
(
GetNavConfig
route
);
/// This function will be called when this Page is called
/// you can use it to change something about the page or give it new page
...
...
@@ -118,7 +119,8 @@ class GetMiddleware implements _RouteMiddleware {
void
onPageDispose
()
{}
@override
GetNavConfig
?
redirectDelegate
(
GetNavConfig
route
)
=>
route
;
Future
<
GetNavConfig
?>
redirectDelegate
(
GetNavConfig
route
)
=>
SynchronousFuture
(
route
);
}
class
MiddlewareRunner
{
...
...
Please
register
or
login
to post a comment