Clean up type/lint errors in modules (#10996)

This commit is contained in:
Samuel Newman
2026-06-26 17:41:09 +03:00
committed by GitHub
parent fcbd23e7db
commit 66250e45cc
10 changed files with 62 additions and 98 deletions
-53
View File
@@ -10,22 +10,9 @@
"count": 2 "count": 2
} }
}, },
"modules/bottom-sheet/src/BottomSheetPortal.tsx": {
"no-restricted-imports": {
"count": 1
}
},
"modules/bottom-sheet/src/lib/Portal.tsx": {
"no-restricted-imports": {
"count": 1
}
},
"modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider.tsx": { "modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider.tsx": {
"@typescript-eslint/no-floating-promises": { "@typescript-eslint/no-floating-promises": {
"count": 1 "count": 1
},
"no-restricted-imports": {
"count": 1
} }
}, },
"modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.web.ts": { "modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.web.ts": {
@@ -33,28 +20,6 @@
"count": 4 "count": 4
} }
}, },
"modules/expo-bluesky-gif-view/src/GifView.tsx": {
"@typescript-eslint/no-explicit-any": {
"count": 2
},
"@typescript-eslint/no-unsafe-call": {
"count": 4
},
"@typescript-eslint/no-unsafe-member-access": {
"count": 4
},
"no-restricted-imports": {
"count": 1
}
},
"modules/expo-bluesky-gif-view/src/GifView.web.tsx": {
"@typescript-eslint/no-floating-promises": {
"count": 2
},
"@typescript-eslint/require-await": {
"count": 2
}
},
"modules/expo-bluesky-swiss-army/src/PlatformInfo/index.native.ts": { "modules/expo-bluesky-swiss-army/src/PlatformInfo/index.native.ts": {
"@typescript-eslint/no-unsafe-call": { "@typescript-eslint/no-unsafe-call": {
"count": 3 "count": 3
@@ -88,9 +53,6 @@
}, },
"@typescript-eslint/no-unsafe-member-access": { "@typescript-eslint/no-unsafe-member-access": {
"count": 1 "count": 1
},
"no-restricted-imports": {
"count": 1
} }
}, },
"modules/expo-bluesky-swiss-army/src/VisibilityView/index.tsx": { "modules/expo-bluesky-swiss-army/src/VisibilityView/index.tsx": {
@@ -98,16 +60,6 @@
"count": 1 "count": 1
} }
}, },
"modules/expo-bluesky-swiss-army/src/VisibilityView/types.ts": {
"no-restricted-imports": {
"count": 1
}
},
"modules/expo-emoji-picker/src/EmojiPickerView.tsx": {
"no-restricted-imports": {
"count": 1
}
},
"src/Navigation.tsx": { "src/Navigation.tsx": {
"@typescript-eslint/no-floating-promises": { "@typescript-eslint/no-floating-promises": {
"count": 1 "count": 1
@@ -2118,11 +2070,6 @@
"count": 1 "count": 1
} }
}, },
"src/view/com/composer/videos/pickVideo.web.ts": {
"@typescript-eslint/no-misused-promises": {
"count": 1
}
},
"src/view/com/feeds/ComposerPrompt.tsx": { "src/view/com/feeds/ComposerPrompt.tsx": {
"@typescript-eslint/no-explicit-any": { "@typescript-eslint/no-explicit-any": {
"count": 2 "count": 2
@@ -1,20 +1,20 @@
import React from 'react' import {createContext, useContext, useMemo} from 'react'
import {createPortalGroup_INTERNAL} from './lib/Portal' import {createPortalGroup_INTERNAL} from './lib/Portal'
type PortalContext = React.ElementType<{children: React.ReactNode}> type PortalContext = React.ElementType<{children: React.ReactNode}>
export const Context = React.createContext({} as PortalContext) export const Context = createContext({} as PortalContext)
Context.displayName = 'BottomSheetPortalContext' Context.displayName = 'BottomSheetPortalContext'
export const useBottomSheetPortal_INTERNAL = () => React.useContext(Context) export const useBottomSheetPortal_INTERNAL = () => useContext(Context)
export function BottomSheetPortalProvider({ export function BottomSheetPortalProvider({
children, children,
}: { }: {
children: React.ReactNode children: React.ReactNode
}) { }) {
const portal = React.useMemo(() => { const portal = useMemo(() => {
return createPortalGroup_INTERNAL() return createPortalGroup_INTERNAL()
}, []) }, [])
+22 -12
View File
@@ -1,4 +1,14 @@
import React from 'react' import {
createContext,
Fragment,
useCallback,
useContext,
useEffect,
useId,
useMemo,
useRef,
useState,
} from 'react'
type Component = React.ReactElement type Component = React.ReactElement
@@ -13,7 +23,7 @@ type ComponentMap = {
} }
export function createPortalGroup_INTERNAL() { export function createPortalGroup_INTERNAL() {
const Context = React.createContext<ContextType>({ const Context = createContext<ContextType>({
outlet: null, outlet: null,
append: () => {}, append: () => {},
remove: () => {}, remove: () => {},
@@ -21,21 +31,21 @@ export function createPortalGroup_INTERNAL() {
Context.displayName = 'BottomSheetPortalContext' Context.displayName = 'BottomSheetPortalContext'
function Provider(props: React.PropsWithChildren<{}>) { function Provider(props: React.PropsWithChildren<{}>) {
const map = React.useRef<ComponentMap>({}) const map = useRef<ComponentMap>({})
const [outlet, setOutlet] = React.useState<ContextType['outlet']>(null) const [outlet, setOutlet] = useState<ContextType['outlet']>(null)
const append = React.useCallback<ContextType['append']>((id, component) => { const append = useCallback<ContextType['append']>((id, component) => {
if (map.current[id]) return if (map.current[id]) return
map.current[id] = <React.Fragment key={id}>{component}</React.Fragment> map.current[id] = <Fragment key={id}>{component}</Fragment>
setOutlet(<>{Object.values(map.current)}</>) setOutlet(<>{Object.values(map.current)}</>)
}, []) }, [])
const remove = React.useCallback<ContextType['remove']>(id => { const remove = useCallback<ContextType['remove']>(id => {
delete map.current[id] delete map.current[id]
setOutlet(<>{Object.values(map.current)}</>) setOutlet(<>{Object.values(map.current)}</>)
}, []) }, [])
const contextValue = React.useMemo( const contextValue = useMemo(
() => ({ () => ({
outlet, outlet,
append, append,
@@ -50,14 +60,14 @@ export function createPortalGroup_INTERNAL() {
} }
function Outlet() { function Outlet() {
const ctx = React.useContext(Context) const ctx = useContext(Context)
return ctx.outlet return ctx.outlet
} }
function Portal({children}: React.PropsWithChildren<{}>) { function Portal({children}: React.PropsWithChildren<{}>) {
const {append, remove} = React.useContext(Context) const {append, remove} = useContext(Context)
const id = React.useId() const id = useId()
React.useEffect(() => { useEffect(() => {
append(id, children as Component) append(id, children as Component)
return () => remove(id) return () => remove(id)
}, [id, children, append, remove]) }, [id, children, append, remove])
@@ -1,4 +1,4 @@
import React from 'react' import {createContext, useContext, useEffect, useMemo, useState} from 'react'
import {type BackgroundNotificationHandlerPreferences} from './ExpoBackgroundNotificationHandler.types' import {type BackgroundNotificationHandlerPreferences} from './ExpoBackgroundNotificationHandler.types'
import {BackgroundNotificationHandler} from './ExpoBackgroundNotificationHandlerModule' import {BackgroundNotificationHandler} from './ExpoBackgroundNotificationHandlerModule'
@@ -11,11 +11,10 @@ interface BackgroundNotificationPreferencesContext {
) => void ) => void
} }
const Context = React.createContext<BackgroundNotificationPreferencesContext>( const Context = createContext<BackgroundNotificationPreferencesContext>(
{} as BackgroundNotificationPreferencesContext, {} as BackgroundNotificationPreferencesContext,
) )
export const useBackgroundNotificationPreferences = () => export const useBackgroundNotificationPreferences = () => useContext(Context)
React.useContext(Context)
export function BackgroundNotificationPreferencesProvider({ export function BackgroundNotificationPreferencesProvider({
children, children,
@@ -23,18 +22,18 @@ export function BackgroundNotificationPreferencesProvider({
children: React.ReactNode children: React.ReactNode
}) { }) {
const [preferences, setPreferences] = const [preferences, setPreferences] =
React.useState<BackgroundNotificationHandlerPreferences>({ useState<BackgroundNotificationHandlerPreferences>({
playSoundChat: true, playSoundChat: true,
}) })
React.useEffect(() => { useEffect(() => {
;(async () => { ;(async () => {
const prefs = await BackgroundNotificationHandler.getAllPrefsAsync() const prefs = await BackgroundNotificationHandler.getAllPrefsAsync()
setPreferences(prefs) setPreferences(prefs)
})() })()
}, []) }, [])
const value = React.useMemo( const value = useMemo(
() => ({ () => ({
preferences, preferences,
setPref: async < setPref: async <
+16 -9
View File
@@ -1,17 +1,24 @@
import React from 'react' import {createRef, PureComponent} from 'react'
import {requireNativeModule} from 'expo' import {requireNativeModule} from 'expo'
import {requireNativeViewManager} from 'expo-modules-core' import {requireNativeViewManager} from 'expo-modules-core'
import {type GifViewProps} from './GifView.types' import {type GifViewProps} from './GifView.types'
const NativeModule = requireNativeModule('ExpoBlueskyGifView') interface GifViewNativeRef {
playAsync: () => Promise<void>
pauseAsync: () => Promise<void>
toggleAsync: () => Promise<void>
}
const NativeModule: {
prefetchAsync: (sources: string[]) => Promise<void>
} = requireNativeModule('ExpoBlueskyGifView')
const NativeView: React.ComponentType< const NativeView: React.ComponentType<
GifViewProps & {ref: React.RefObject<any>} GifViewProps & {ref: React.RefObject<GifViewNativeRef | null>}
> = requireNativeViewManager('ExpoBlueskyGifView') > = requireNativeViewManager('ExpoBlueskyGifView')
export class GifView extends React.PureComponent<GifViewProps> { export class GifView extends PureComponent<GifViewProps> {
// TODO native types, should all be the same as those in this class private nativeRef: React.RefObject<GifViewNativeRef | null> = createRef()
private nativeRef: React.RefObject<any> = React.createRef()
constructor(props: GifViewProps | Readonly<GifViewProps>) { constructor(props: GifViewProps | Readonly<GifViewProps>) {
super(props) super(props)
@@ -22,15 +29,15 @@ export class GifView extends React.PureComponent<GifViewProps> {
} }
async playAsync(): Promise<void> { async playAsync(): Promise<void> {
await this.nativeRef.current.playAsync() await this.nativeRef.current?.playAsync()
} }
async pauseAsync(): Promise<void> { async pauseAsync(): Promise<void> {
await this.nativeRef.current.pauseAsync() await this.nativeRef.current?.pauseAsync()
} }
async toggleAsync(): Promise<void> { async toggleAsync(): Promise<void> {
await this.nativeRef.current.toggleAsync() await this.nativeRef.current?.toggleAsync()
} }
render() { render() {
@@ -1,10 +1,11 @@
import {createRef, PureComponent, type RefObject} from 'react' import {createRef, PureComponent} from 'react'
import {StyleSheet} from 'react-native' import {StyleSheet} from 'react-native'
import {type GifViewProps} from './GifView.types' import {type GifViewProps} from './GifView.types'
export class GifView extends PureComponent<GifViewProps> { export class GifView extends PureComponent<GifViewProps> {
private readonly videoPlayerRef: RefObject<HTMLMediaElement> = createRef() private readonly videoPlayerRef: React.RefObject<HTMLVideoElement | null> =
createRef()
private isLoaded = false private isLoaded = false
constructor(props: GifViewProps | Readonly<GifViewProps>) { constructor(props: GifViewProps | Readonly<GifViewProps>) {
@@ -18,9 +19,9 @@ export class GifView extends PureComponent<GifViewProps> {
componentDidUpdate(prevProps: Readonly<GifViewProps>) { componentDidUpdate(prevProps: Readonly<GifViewProps>) {
if (prevProps.autoplay !== this.props.autoplay) { if (prevProps.autoplay !== this.props.autoplay) {
if (this.props.autoplay) { if (this.props.autoplay) {
this.playAsync() void this.playAsync()
} else { } else {
this.pauseAsync() void this.pauseAsync()
} }
} }
} }
@@ -29,6 +30,7 @@ export class GifView extends PureComponent<GifViewProps> {
document.removeEventListener('visibilitychange', this.onVisibilityChange) document.removeEventListener('visibilitychange', this.onVisibilityChange)
} }
// eslint-disable-next-line @typescript-eslint/require-await
static async prefetchAsync(_: string[]): Promise<void> { static async prefetchAsync(_: string[]): Promise<void> {
console.warn('prefetchAsync is not supported on web') console.warn('prefetchAsync is not supported on web')
} }
@@ -81,6 +83,7 @@ export class GifView extends PureComponent<GifViewProps> {
} }
} }
// eslint-disable-next-line @typescript-eslint/require-await
async pauseAsync(): Promise<void> { async pauseAsync(): Promise<void> {
this.videoPlayerRef.current?.pause() this.videoPlayerRef.current?.pause()
} }
@@ -102,12 +105,12 @@ export class GifView extends PureComponent<GifViewProps> {
// When `<source>` children are present, omit `src` so the browser // When `<source>` children are present, omit `src` so the browser
// walks the source list and picks via canPlayType. // walks the source list and picks via canPlayType.
src={useSources ? undefined : source} src={useSources ? undefined : source}
autoPlay={autoplay ? 'autoplay' : undefined} autoPlay={autoplay ? true : undefined}
preload={autoplay ? 'auto' : undefined} preload={autoplay ? 'auto' : undefined}
playsInline={true} playsInline={true}
loop="loop" loop={true}
muted="muted" muted={true}
style={StyleSheet.flatten(style)} style={StyleSheet.flatten(style) as React.CSSProperties}
onCanPlay={this.onLoad} onCanPlay={this.onLoad}
onPlay={this.firePlayerStateChangeEvent} onPlay={this.firePlayerStateChangeEvent}
onPause={this.firePlayerStateChangeEvent} onPause={this.firePlayerStateChangeEvent}
@@ -1,4 +1,4 @@
import React from 'react' import {useCallback} from 'react'
import {type StyleProp, type ViewStyle} from 'react-native' import {type StyleProp, type ViewStyle} from 'react-native'
import {requireNativeModule, requireNativeViewManager} from 'expo-modules-core' import {requireNativeModule, requireNativeViewManager} from 'expo-modules-core'
@@ -21,7 +21,7 @@ export default function VisibilityView({
onChangeStatus: onChangeStatusOuter, onChangeStatus: onChangeStatusOuter,
enabled, enabled,
}: VisibilityViewProps) { }: VisibilityViewProps) {
const onChangeStatus = React.useCallback( const onChangeStatus = useCallback(
(e: {nativeEvent: {isActive: boolean}}) => { (e: {nativeEvent: {isActive: boolean}}) => {
onChangeStatusOuter(e.nativeEvent.isActive) onChangeStatusOuter(e.nativeEvent.isActive)
}, },
@@ -1,4 +1,3 @@
import type React from 'react'
export interface VisibilityViewProps { export interface VisibilityViewProps {
children: React.ReactNode children: React.ReactNode
onChangeStatus: (isActive: boolean) => void onChangeStatus: (isActive: boolean) => void
@@ -1,5 +1,4 @@
import {requireNativeView} from 'expo' import {requireNativeView} from 'expo'
import type * as React from 'react'
import { import {
type EmojiPickerNativeViewProps, type EmojiPickerNativeViewProps,
+1 -1
View File
@@ -1,4 +1,4 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"include": ["src", "app.config.js"] "include": ["src", "modules", "app.config.js"]
} }