Give explicit names to MobX observer components (#1413)

* Consider observer(...) as components

* Add display names to MobX observers

* Temporarily suppress nested components

* Suppress new false positives for react/prop-types
This commit is contained in:
dan 2023-09-08 01:36:08 +01:00 committed by GitHub
parent 69209c988f
commit 8a93321fb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 2868 additions and 2836 deletions

View file

@ -6,73 +6,71 @@ import {ComposerOpts} from 'state/models/ui/shell'
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
import {usePalette} from 'lib/hooks/usePalette'
export const Composer = observer(
({
active,
winHeight,
replyTo,
onPost,
onClose,
quote,
mention,
}: {
active: boolean
winHeight: number
replyTo?: ComposerOpts['replyTo']
onPost?: ComposerOpts['onPost']
onClose: () => void
quote?: ComposerOpts['quote']
mention?: ComposerOpts['mention']
}) => {
const pal = usePalette('default')
const initInterp = useAnimatedValue(0)
export const Composer = observer(function ComposerImpl({
active,
winHeight,
replyTo,
onPost,
onClose,
quote,
mention,
}: {
active: boolean
winHeight: number
replyTo?: ComposerOpts['replyTo']
onPost?: ComposerOpts['onPost']
onClose: () => void
quote?: ComposerOpts['quote']
mention?: ComposerOpts['mention']
}) {
const pal = usePalette('default')
const initInterp = useAnimatedValue(0)
useEffect(() => {
if (active) {
Animated.timing(initInterp, {
toValue: 1,
duration: 300,
easing: Easing.out(Easing.exp),
useNativeDriver: true,
}).start()
} else {
initInterp.setValue(0)
}
}, [initInterp, active])
const wrapperAnimStyle = {
transform: [
{
translateY: initInterp.interpolate({
inputRange: [0, 1],
outputRange: [winHeight, 0],
}),
},
],
useEffect(() => {
if (active) {
Animated.timing(initInterp, {
toValue: 1,
duration: 300,
easing: Easing.out(Easing.exp),
useNativeDriver: true,
}).start()
} else {
initInterp.setValue(0)
}
}, [initInterp, active])
const wrapperAnimStyle = {
transform: [
{
translateY: initInterp.interpolate({
inputRange: [0, 1],
outputRange: [winHeight, 0],
}),
},
],
}
// rendering
// =
// rendering
// =
if (!active) {
return <View />
}
if (!active) {
return <View />
}
return (
<Animated.View
style={[styles.wrapper, pal.view, wrapperAnimStyle]}
aria-modal
accessibilityViewIsModal>
<ComposePost
replyTo={replyTo}
onPost={onPost}
onClose={onClose}
quote={quote}
mention={mention}
/>
</Animated.View>
)
},
)
return (
<Animated.View
style={[styles.wrapper, pal.view, wrapperAnimStyle]}
aria-modal
accessibilityViewIsModal>
<ComposePost
replyTo={replyTo}
onPost={onPost}
onClose={onClose}
quote={quote}
mention={mention}
/>
</Animated.View>
)
})
const styles = StyleSheet.create({
wrapper: {

View file

@ -8,54 +8,52 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
const BOTTOM_BAR_HEIGHT = 61
export const Composer = observer(
({
active,
replyTo,
quote,
onPost,
onClose,
mention,
}: {
active: boolean
winHeight: number
replyTo?: ComposerOpts['replyTo']
quote: ComposerOpts['quote']
onPost?: ComposerOpts['onPost']
onClose: () => void
mention?: ComposerOpts['mention']
}) => {
const pal = usePalette('default')
const {isMobile} = useWebMediaQueries()
export const Composer = observer(function ComposerImpl({
active,
replyTo,
quote,
onPost,
onClose,
mention,
}: {
active: boolean
winHeight: number
replyTo?: ComposerOpts['replyTo']
quote: ComposerOpts['quote']
onPost?: ComposerOpts['onPost']
onClose: () => void
mention?: ComposerOpts['mention']
}) {
const pal = usePalette('default')
const {isMobile} = useWebMediaQueries()
// rendering
// =
// rendering
// =
if (!active) {
return <View />
}
if (!active) {
return <View />
}
return (
<View style={styles.mask} aria-modal accessibilityViewIsModal>
<View
style={[
styles.container,
isMobile && styles.containerMobile,
pal.view,
pal.border,
]}>
<ComposePost
replyTo={replyTo}
quote={quote}
onPost={onPost}
onClose={onClose}
mention={mention}
/>
</View>
return (
<View style={styles.mask} aria-modal accessibilityViewIsModal>
<View
style={[
styles.container,
isMobile && styles.containerMobile,
pal.view,
pal.border,
]}>
<ComposePost
replyTo={replyTo}
quote={quote}
onPost={onPost}
onClose={onClose}
mention={mention}
/>
</View>
)
},
)
</View>
)
})
const styles = StyleSheet.create({
mask: {

View file

@ -44,7 +44,7 @@ import {useNavigationTabState} from 'lib/hooks/useNavigationTabState'
import {isWeb} from 'platform/detection'
import {formatCount, formatCountShortOnly} from 'view/com/util/numeric/format'
export const DrawerContent = observer(() => {
export const DrawerContent = observer(function DrawerContentImpl() {
const theme = useTheme()
const pal = usePalette('default')
const store = useStores()
@ -400,7 +400,7 @@ function MenuItem({
)
}
const InviteCodes = observer(() => {
const InviteCodes = observer(function InviteCodesImpl() {
const {track} = useAnalytics()
const store = useStores()
const pal = usePalette('default')

View file

@ -32,7 +32,9 @@ import {UserAvatar} from 'view/com/util/UserAvatar'
type TabOptions = 'Home' | 'Search' | 'Notifications' | 'MyProfile' | 'Feeds'
export const BottomBar = observer(({navigation}: BottomTabBarProps) => {
export const BottomBar = observer(function BottomBarImpl({
navigation,
}: BottomTabBarProps) {
const store = useStores()
const pal = usePalette('default')
const safeAreaInsets = useSafeAreaInsets()

View file

@ -23,7 +23,7 @@ import {Link} from 'view/com/util/Link'
import {useMinimalShellMode} from 'lib/hooks/useMinimalShellMode'
import {makeProfileLink} from 'lib/routes/links'
export const BottomBarWeb = observer(() => {
export const BottomBarWeb = observer(function BottomBarWebImpl() {
const store = useStores()
const pal = usePalette('default')
const safeAreaInsets = useSafeAreaInsets()

View file

@ -40,7 +40,7 @@ import {NavigationProp, CommonNavigatorParams} from 'lib/routes/types'
import {router} from '../../../routes'
import {makeProfileLink} from 'lib/routes/links'
const ProfileCard = observer(() => {
const ProfileCard = observer(function ProfileCardImpl() {
const store = useStores()
const {isDesktop} = useWebMediaQueries()
const size = isDesktop ? 64 : 48
@ -103,78 +103,82 @@ interface NavItemProps {
iconFilled: JSX.Element
label: string
}
const NavItem = observer(
({count, href, icon, iconFilled, label}: NavItemProps) => {
const pal = usePalette('default')
const store = useStores()
const {isDesktop, isTablet} = useWebMediaQueries()
const [pathName] = React.useMemo(() => router.matchPath(href), [href])
const currentRouteInfo = useNavigationState(state => {
if (!state) {
return {name: 'Home'}
const NavItem = observer(function NavItemImpl({
count,
href,
icon,
iconFilled,
label,
}: NavItemProps) {
const pal = usePalette('default')
const store = useStores()
const {isDesktop, isTablet} = useWebMediaQueries()
const [pathName] = React.useMemo(() => router.matchPath(href), [href])
const currentRouteInfo = useNavigationState(state => {
if (!state) {
return {name: 'Home'}
}
return getCurrentRoute(state)
})
let isCurrent =
currentRouteInfo.name === 'Profile'
? isTab(currentRouteInfo.name, pathName) &&
(currentRouteInfo.params as CommonNavigatorParams['Profile']).name ===
store.me.handle
: isTab(currentRouteInfo.name, pathName)
const {onPress} = useLinkProps({to: href})
const onPressWrapped = React.useCallback(
(e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
if (e.ctrlKey || e.metaKey || e.altKey) {
return
}
return getCurrentRoute(state)
})
let isCurrent =
currentRouteInfo.name === 'Profile'
? isTab(currentRouteInfo.name, pathName) &&
(currentRouteInfo.params as CommonNavigatorParams['Profile']).name ===
store.me.handle
: isTab(currentRouteInfo.name, pathName)
const {onPress} = useLinkProps({to: href})
const onPressWrapped = React.useCallback(
(e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
if (e.ctrlKey || e.metaKey || e.altKey) {
return
}
e.preventDefault()
if (isCurrent) {
store.emitScreenSoftReset()
} else {
onPress()
}
},
[onPress, isCurrent, store],
)
e.preventDefault()
if (isCurrent) {
store.emitScreenSoftReset()
} else {
onPress()
}
},
[onPress, isCurrent, store],
)
return (
<PressableWithHover
style={styles.navItemWrapper}
hoverStyle={pal.viewLight}
// @ts-ignore the function signature differs on web -prf
onPress={onPressWrapped}
// @ts-ignore web only -prf
href={href}
dataSet={{noUnderline: 1}}
accessibilityRole="tab"
accessibilityLabel={label}
accessibilityHint="">
<View
style={[
styles.navItemIconWrapper,
isTablet && styles.navItemIconWrapperTablet,
]}>
{isCurrent ? iconFilled : icon}
{typeof count === 'string' && count ? (
<Text
type="button"
style={[
styles.navItemCount,
isTablet && styles.navItemCountTablet,
]}>
{count}
</Text>
) : null}
</View>
{isDesktop && (
<Text type="title" style={[isCurrent ? s.bold : s.normal, pal.text]}>
{label}
return (
<PressableWithHover
style={styles.navItemWrapper}
hoverStyle={pal.viewLight}
// @ts-ignore the function signature differs on web -prf
onPress={onPressWrapped}
// @ts-ignore web only -prf
href={href}
dataSet={{noUnderline: 1}}
accessibilityRole="tab"
accessibilityLabel={label}
accessibilityHint="">
<View
style={[
styles.navItemIconWrapper,
isTablet && styles.navItemIconWrapperTablet,
]}>
{isCurrent ? iconFilled : icon}
{typeof count === 'string' && count ? (
<Text
type="button"
style={[
styles.navItemCount,
isTablet && styles.navItemCountTablet,
]}>
{count}
</Text>
)}
</PressableWithHover>
)
},
)
) : null}
</View>
{isDesktop && (
<Text type="title" style={[isCurrent ? s.bold : s.normal, pal.text]}>
{label}
</Text>
)}
</PressableWithHover>
)
})
function ComposeBtn() {
const store = useStores()

View file

@ -13,7 +13,7 @@ import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {pluralize} from 'lib/strings/helpers'
import {formatCount} from 'view/com/util/numeric/format'
export const DesktopRightNav = observer(function DesktopRightNav() {
export const DesktopRightNav = observer(function DesktopRightNavImpl() {
const store = useStores()
const pal = usePalette('default')
const palError = usePalette('error')
@ -78,7 +78,7 @@ export const DesktopRightNav = observer(function DesktopRightNav() {
)
})
const InviteCodes = observer(() => {
const InviteCodes = observer(function InviteCodesImpl() {
const store = useStores()
const pal = usePalette('default')

View file

@ -24,7 +24,7 @@ import {isStateAtTabRoot} from 'lib/routes/helpers'
import {SafeAreaProvider} from 'react-native-safe-area-context'
import {useOTAUpdate} from 'lib/hooks/useOTAUpdate'
const ShellInner = observer(() => {
const ShellInner = observer(function ShellInnerImpl() {
const store = useStores()
useOTAUpdate() // this hook polls for OTA updates every few seconds
const winDim = useWindowDimensions()
@ -81,7 +81,7 @@ const ShellInner = observer(() => {
)
})
export const Shell: React.FC = observer(() => {
export const Shell: React.FC = observer(function ShellImpl() {
const pal = usePalette('default')
const theme = useTheme()
return (

View file

@ -17,7 +17,7 @@ import {BottomBarWeb} from './bottom-bar/BottomBarWeb'
import {useNavigation} from '@react-navigation/native'
import {NavigationProp} from 'lib/routes/types'
const ShellInner = observer(() => {
const ShellInner = observer(function ShellInnerImpl() {
const store = useStores()
const {isDesktop, isMobile} = useWebMediaQueries()
const navigator = useNavigation<NavigationProp>()
@ -71,7 +71,7 @@ const ShellInner = observer(() => {
)
})
export const Shell: React.FC = observer(() => {
export const Shell: React.FC = observer(function ShellImpl() {
const pageBg = useColorSchemeStyle(styles.bgLight, styles.bgDark)
return (
<View style={[s.hContentRegion, pageBg]}>