diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-11-24 18:13:42 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-11-28 17:09:52 +0100 |
| commit | 1de7b90fc7fefb137849b5404db2c30241bcffde (patch) | |
| tree | 1fc91e479aa266893e19fa73af564a794a5d1b0a /gui/src | |
| parent | 10142a6a52768c374d62c99addcd80d5a07f44b9 (diff) | |
| download | mullvadvpn-1de7b90fc7fefb137849b5404db2c30241bcffde.tar.xz mullvadvpn-1de7b90fc7fefb137849b5404db2c30241bcffde.zip | |
Add transition to location state
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/renderer/lib/history.tsx | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/gui/src/renderer/lib/history.tsx b/gui/src/renderer/lib/history.tsx index b81aef50fe..68cbbcf482 100644 --- a/gui/src/renderer/lib/history.tsx +++ b/gui/src/renderer/lib/history.tsx @@ -39,6 +39,21 @@ export const transitions: ITransitionMap = { }, }; +const transitionOpposites: Record<string, string> = { + 'slide-up': 'slide-down', + 'slide-down': 'slide-up', + push: 'pop', + pop: 'push', + '': '', +}; + +function oppositeTransition(transition: ITransitionSpecification): ITransitionSpecification { + return { + ...transition, + name: transitionOpposites[transition.name], + }; +} + type LocationDescriptor = RoutePath | GeneratedRoutePath | LocationDescriptorObject<LocationState>; type LocationListener = ( @@ -78,39 +93,26 @@ export default class History { return this.lastAction; } - public push = (nextLocation: LocationDescriptor, nextState?: LocationState) => { - this.pushImpl(nextLocation, nextState); - this.notify(transitions.push); - }; - - public pop = () => { - if (this.popImpl()) { - this.notify(transitions.pop); - } - }; - - public show = (nextLocation: LocationDescriptor, nextState?: LocationState) => { - this.pushImpl(nextLocation, nextState); - this.notify(transitions.show); + public push = (nextLocation: LocationDescriptor, nextState?: Partial<LocationState>) => { + const state = { transition: transitions.push, ...nextState }; + this.pushImpl(nextLocation, state); + this.notify(state.transition); }; - public dismiss = (all?: boolean, transition = transitions.dismiss) => { - if (this.popImpl(all ? this.index : 1)) { + public pop = (all?: boolean) => { + const transition = this.popImpl(all === true ? this.index : 1); + if (transition !== undefined) { this.notify(transition); } }; - public reset = ( - nextLocation: LocationDescriptor, - transition?: ITransitionSpecification, - nextState?: LocationState, - ) => { + public reset = (nextLocation: LocationDescriptor, nextState?: Partial<LocationState>) => { const location = this.createLocation(nextLocation, nextState); this.lastAction = 'REPLACE'; this.index = 0; this.entries = [location]; - this.notify(transition ?? transitions.none); + this.notify(nextState?.transition ?? transitions.none); }; public listen(callback: LocationListener) { @@ -158,22 +160,24 @@ export default class History { throw Error('Not implemented'); } - private pushImpl(nextLocation: LocationDescriptor, nextState?: LocationState) { + private pushImpl(nextLocation: LocationDescriptor, nextState?: Partial<LocationState>) { const location = this.createLocation(nextLocation, nextState); this.lastAction = 'PUSH'; this.index += 1; this.entries.splice(this.index, this.entries.length - this.index, location); } - private popImpl(n = 1): boolean { + private popImpl(n = 1): ITransitionSpecification | undefined { if (this.canGo(-n)) { this.lastAction = 'POP'; this.index -= n; + + const transition = this.entries[this.index + 1].state.transition; this.entries = this.entries.slice(0, this.index + 1); - return true; + return oppositeTransition(transition); } else { - return false; + return undefined; } } @@ -183,7 +187,7 @@ export default class History { private createLocation( location: LocationDescriptor, - state?: LocationState, + state?: Partial<LocationState>, ): Location<LocationState> { if (typeof location === 'string') { return this.createLocationFromString(location, state); @@ -194,22 +198,33 @@ export default class History { pathname: location.pathname ?? this.location.pathname, search: location.search ?? '', hash: location.hash ?? '', - state: location.state ?? { scrollPosition: [0, 0], expandedSections: {} }, + state: this.createState(state), key: location.key ?? this.getRandomKey(), }; } } - private createLocationFromString(path: string, state?: LocationState): Location<LocationState> { + private createLocationFromString( + path: string, + state?: Partial<LocationState>, + ): Location<LocationState> { return { pathname: path, search: '', hash: '', - state: state ?? { scrollPosition: [0, 0], expandedSections: {} }, + state: this.createState(state), key: this.getRandomKey(), }; } + private createState(state?: Partial<LocationState>): LocationState { + return { + scrollPosition: state?.scrollPosition ?? [0, 0], + expandedSections: state?.expandedSections ?? {}, + transition: state?.transition ?? transitions.none, + }; + } + private getRandomKey() { return Math.random().toString(36).substr(8); } |
