11import { Injectable } from '@angular/core' ;
22import { Router , NavigationEnd } from '@angular/router' ;
3- import { filter } from 'rxjs/operators' ;
3+ import { filter , tap , takeWhile } from 'rxjs/operators' ;
44import { NavController , Platform } from '@ionic/angular' ;
5+ import { Navigateable } from '../interfaces' ;
6+ import { fromEvent , zip , race , from } from 'rxjs' ;
57
68export interface RoutingStateConfig {
79 clearOn : string [ ] ;
@@ -12,7 +14,7 @@ export interface RoutingStateConfig {
1214 providedIn : 'root'
1315} )
1416export class FivRoutingStateService {
15- private history : string [ ] = [ ] ;
17+ private history : ( string | Navigateable ) [ ] = [ ] ;
1618 private config : RoutingStateConfig ;
1719
1820 constructor (
@@ -32,7 +34,7 @@ export class FivRoutingStateService {
3234 this . pop ( ) ;
3335 }
3436 // add url to history
35- this . history = [ ... this . history , urlAfterRedirects ] ;
37+ this . history . push ( urlAfterRedirects ) ;
3638 if ( this . config && this . config . clearOn ) {
3739 const clear = this . config . clearOn . some ( s => s === urlAfterRedirects ) ;
3840 if ( clear ) {
@@ -42,27 +44,40 @@ export class FivRoutingStateService {
4244 } ) ;
4345 }
4446
47+ registerNavigateable ( target : Navigateable ) {
48+ if ( isNavigateable ( target ) ) {
49+ this . history . push ( target ) ;
50+ }
51+ }
52+
4553 handleAndroidBackButton ( ) {
46- this . platform . backButton . subscribe ( ( ) => {
47- if ( this . getHistory ( ) . length <= 1 ) {
48- // close the app because we are at root level
49- navigator [ 'app' ] . exitApp ( ) ;
50- } else {
51- // go back
54+ this . platform . backButton
55+ . pipe ( filter ( ( ) => ! isNavigateable ( this . getCurrentUrl ( ) ) ) )
56+ . subscribe ( event => {
5257 this . goBack ( ) ;
53- }
54- } ) ;
58+ } ) ;
59+
60+ this . platform . backButton
61+ . pipe ( filter ( ( ) => isNavigateable ( this . getCurrentUrl ( ) ) ) )
62+ . subscribe ( event => {
63+ event . register ( 99999 , ( ) => {
64+ this . goBack ( '/' ) ;
65+ } ) ;
66+ } ) ;
5567 }
5668
57- public getHistory ( ) : string [ ] {
69+ public getHistory ( ) : ( string | Navigateable ) [ ] {
5870 return this . history ;
5971 }
6072
61- public getPreviousUrl ( defaultHref = '/' ) : string {
62- return this . history [ this . history . length - 2 ] || defaultHref ;
73+ public getPreviousUrl ( defaultHref = '/' ) : string | Navigateable {
74+ if ( this . history . length > 2 ) {
75+ return this . history [ this . history . length - 2 ] ;
76+ }
77+ return defaultHref ;
6378 }
6479
65- public pop ( ) : string {
80+ public pop ( ) : string | Navigateable {
6681 return this . history . pop ( ) ;
6782 }
6883
@@ -84,11 +99,40 @@ export class FivRoutingStateService {
8499 }
85100 }
86101
87- public getCurrentUrl ( ) : string {
102+ public getCurrentUrl ( ) : string | Navigateable {
88103 return this . history [ this . history . length - 1 ] ;
89104 }
90105
91106 goBack ( defaultHref = '/' ) {
92- this . navCtrl . navigateBack ( this . getPreviousUrl ( defaultHref ) ) ;
107+ if ( this . getHistory ( ) . length <= 1 ) {
108+ // close the app because we are at root level
109+ return navigator [ 'app' ] . exitApp ( ) ;
110+ }
111+ const current = this . getCurrentUrl ( ) ;
112+ if ( typeof current !== 'string' && isNavigateable ( current ) ) {
113+ current . dismiss ( ) ;
114+ return this . pop ( ) ;
115+ }
116+
117+ const previous = this . getPreviousUrl ( defaultHref ) ;
118+ if ( typeof previous === 'string' ) {
119+ return this . navCtrl . navigateBack ( previous ) ;
120+ }
121+ if ( isNavigateable ( previous ) ) {
122+ return this . navCtrl . navigateBack ( this . getLatestUrl ( defaultHref ) ) ;
123+ }
124+ }
125+
126+ getLatestUrl ( defaultHref : string ) : string {
127+ const urls = this . history . filter ( e => ! ! ( typeof e === 'string' ) ) ;
128+ const latest = urls [ urls . length - 1 ] ;
129+ if ( urls . length > 0 && latest && typeof latest === 'string' ) {
130+ return latest ;
131+ }
132+ return defaultHref ;
93133 }
94134}
135+
136+ export function isNavigateable ( object : any ) : boolean {
137+ return ! ! object && object . dismiss !== undefined ;
138+ }
0 commit comments