Fix using screen names in Link (#8473)
* use our router in favour of useLinkBuilder * test feature using Home header feeds button * handle non-string params properly
This commit is contained in:
@@ -4,7 +4,6 @@ import {sanitizeUrl} from '@braintree/sanitize-url'
|
|||||||
import {
|
import {
|
||||||
type LinkProps as RNLinkProps,
|
type LinkProps as RNLinkProps,
|
||||||
StackActions,
|
StackActions,
|
||||||
useLinkBuilder,
|
|
||||||
} from '@react-navigation/native'
|
} from '@react-navigation/native'
|
||||||
|
|
||||||
import {BSKY_DOWNLOAD_URL} from '#/lib/constants'
|
import {BSKY_DOWNLOAD_URL} from '#/lib/constants'
|
||||||
@@ -95,20 +94,19 @@ export function useLink({
|
|||||||
shouldProxy?: boolean
|
shouldProxy?: boolean
|
||||||
}) {
|
}) {
|
||||||
const navigation = useNavigationDeduped()
|
const navigation = useNavigationDeduped()
|
||||||
const {buildHref} = useLinkBuilder()
|
|
||||||
const href = useMemo(() => {
|
const href = useMemo(() => {
|
||||||
return typeof to === 'string'
|
return typeof to === 'string'
|
||||||
? convertBskyAppUrlIfNeeded(sanitizeUrl(to))
|
? convertBskyAppUrlIfNeeded(sanitizeUrl(to))
|
||||||
: to.screen
|
: to.screen
|
||||||
? buildHref(to.screen, to.params)
|
? router.matchName(to.screen)?.build(to.params)
|
||||||
: to.href
|
: to.href
|
||||||
? convertBskyAppUrlIfNeeded(sanitizeUrl(to.href))
|
? convertBskyAppUrlIfNeeded(sanitizeUrl(to.href))
|
||||||
: undefined
|
: undefined
|
||||||
}, [to, buildHref])
|
}, [to])
|
||||||
|
|
||||||
if (!href) {
|
if (!href) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Link `to` prop must be a string or an object with `screen` and `params` properties',
|
'Could not resolve screen. Link `to` prop must be a string or an object with `screen` and `params` properties',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Route, RouteParams} from './types'
|
import {type Route, type RouteParams} from './types'
|
||||||
|
|
||||||
export class Router {
|
export class Router {
|
||||||
routes: [string, Route][] = []
|
routes: [string, Route][] = []
|
||||||
@@ -45,7 +45,7 @@ function createRoute(pattern: string): Route {
|
|||||||
})
|
})
|
||||||
const matcherRe = new RegExp(`^${matcherReInternal}([?]|$)`, 'i')
|
const matcherRe = new RegExp(`^${matcherReInternal}([?]|$)`, 'i')
|
||||||
return {
|
return {
|
||||||
match(path: string) {
|
match(path) {
|
||||||
const {pathname, searchParams} = new URL(path, 'http://throwaway.com')
|
const {pathname, searchParams} = new URL(path, 'http://throwaway.com')
|
||||||
const addedParams = Object.fromEntries(searchParams.entries())
|
const addedParams = Object.fromEntries(searchParams.entries())
|
||||||
|
|
||||||
@@ -55,10 +55,10 @@ function createRoute(pattern: string): Route {
|
|||||||
}
|
}
|
||||||
return undefined
|
return undefined
|
||||||
},
|
},
|
||||||
build(params: Record<string, string>) {
|
build(params = {}) {
|
||||||
const str = pattern.replace(
|
const str = pattern.replace(
|
||||||
/:([\w]+)/g,
|
/:([\w]+)/g,
|
||||||
(_m, name) => params[name] || 'undefined',
|
(_m, name) => params[encodeURIComponent(name)] || 'undefined',
|
||||||
)
|
)
|
||||||
|
|
||||||
let hasQp = false
|
let hasQp = false
|
||||||
|
|||||||
@@ -143,5 +143,5 @@ export type RouteParams = Record<string, string>
|
|||||||
export type MatchResult = {params: RouteParams}
|
export type MatchResult = {params: RouteParams}
|
||||||
export type Route = {
|
export type Route = {
|
||||||
match: (path: string) => MatchResult | undefined
|
match: (path: string) => MatchResult | undefined
|
||||||
build: (params: RouteParams) => string
|
build: (params?: Record<string, any>) => string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import React from 'react'
|
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import Animated from 'react-native-reanimated'
|
import Animated from 'react-native-reanimated'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
@@ -56,13 +55,8 @@ export function HomeHeaderLayoutMobile({
|
|||||||
<PressableScale
|
<PressableScale
|
||||||
targetScale={0.9}
|
targetScale={0.9}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
emitSoftReset()
|
|
||||||
}}
|
|
||||||
onPressIn={() => {
|
|
||||||
playHaptic('Heavy')
|
|
||||||
}}
|
|
||||||
onPressOut={() => {
|
|
||||||
playHaptic('Light')
|
playHaptic('Light')
|
||||||
|
emitSoftReset()
|
||||||
}}>
|
}}>
|
||||||
<Logo width={30} />
|
<Logo width={30} />
|
||||||
</PressableScale>
|
</PressableScale>
|
||||||
@@ -72,7 +66,7 @@ export function HomeHeaderLayoutMobile({
|
|||||||
{hasSession && (
|
{hasSession && (
|
||||||
<Link
|
<Link
|
||||||
testID="viewHeaderHomeFeedPrefsBtn"
|
testID="viewHeaderHomeFeedPrefsBtn"
|
||||||
to="/feeds"
|
to={{screen: 'Feeds'}}
|
||||||
hitSlop={HITSLOP_10}
|
hitSlop={HITSLOP_10}
|
||||||
label={_(msg`View your feeds and explore more`)}
|
label={_(msg`View your feeds and explore more`)}
|
||||||
size="small"
|
size="small"
|
||||||
@@ -81,9 +75,7 @@ export function HomeHeaderLayoutMobile({
|
|||||||
shape="square"
|
shape="square"
|
||||||
style={[
|
style={[
|
||||||
a.justify_center,
|
a.justify_center,
|
||||||
{
|
{marginRight: -Layout.BUTTON_VISUAL_ALIGNMENT_OFFSET},
|
||||||
marginRight: -Layout.BUTTON_VISUAL_ALIGNMENT_OFFSET,
|
|
||||||
},
|
|
||||||
]}>
|
]}>
|
||||||
<ButtonIcon icon={FeedsIcon} size="lg" />
|
<ButtonIcon icon={FeedsIcon} size="lg" />
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
Reference in New Issue
Block a user