forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {type NavigationProp} from '@react-navigation/native'
2
3import {type RouteParams, type State} from './types'
4
5export function getRootNavigation<T extends {}>(
6 nav: NavigationProp<T>,
7): NavigationProp<T> {
8 while (nav.getParent()) {
9 nav = nav.getParent()
10 }
11 return nav
12}
13
14export function getCurrentRoute(state?: State) {
15 if (!state) {
16 return {name: 'Home'}
17 }
18
19 let node = state.routes[state.index || 0]
20 while (node.state?.routes && typeof node.state?.index === 'number') {
21 node = node.state?.routes[node.state?.index]
22 }
23 return node
24}
25
26export function isStateAtTabRoot(state: State | undefined) {
27 if (!state) {
28 // NOTE
29 // if state is not defined it's because init is occurring
30 // and therefore we can safely assume we're at root
31 // -prf
32 return true
33 }
34 const currentRoute = getCurrentRoute(state)
35 return (
36 isTab(currentRoute.name, 'Home') ||
37 isTab(currentRoute.name, 'Search') ||
38 isTab(currentRoute.name, 'Messages') ||
39 isTab(currentRoute.name, 'Notifications') ||
40 isTab(currentRoute.name, 'MyProfile')
41 )
42}
43
44export function isTab(current: string, route: string) {
45 // NOTE
46 // our tab routes can be variously referenced by 3 different names
47 // this helper deals with that weirdness
48 // -prf
49 return (
50 current === route ||
51 current === `${route}Tab` ||
52 current === `${route}Inner`
53 )
54}
55
56export enum TabState {
57 InsideAtRoot,
58 Inside,
59 Outside,
60}
61export function getTabState(state: State | undefined, tab: string): TabState {
62 if (!state) {
63 return TabState.Outside
64 }
65 const currentRoute = getCurrentRoute(state)
66 if (isTab(currentRoute.name, tab)) {
67 return TabState.InsideAtRoot
68 } else if (isTab(state.routes[state.index || 0].name, tab)) {
69 return TabState.Inside
70 }
71 return TabState.Outside
72}
73
74type ExistingState = {
75 name: string
76 params?: RouteParams
77}
78export function buildStateObject(
79 stack: string,
80 route: string,
81 params: RouteParams,
82 state: ExistingState[] = [],
83) {
84 if (stack === 'Flat') {
85 return {
86 routes: [{name: route, params}],
87 }
88 }
89 return {
90 routes: [
91 {
92 name: stack,
93 state: {
94 routes: [...state, {name: route, params}],
95 },
96 },
97 ],
98 }
99}