|
| 1 | +import type { HybridViewProps } from 'react-native-nitro-modules'; |
| 2 | +import type { RiveFile } from '../specs/RiveFile.nitro'; |
| 3 | +import '../specs/RiveView.nitro'; |
| 4 | +import type { Alignment } from './Alignment'; |
| 5 | +import type { Fit } from './Fit'; |
| 6 | +import { NitroRiveView } from 'react-native-rive'; |
| 7 | +import type { ReferencedAssets } from '../hooks/useRiveFile'; |
| 8 | +import type { RiveFileInput } from '../../lib/typescript/src'; |
| 9 | +import { useRiveFile } from '../hooks/useRiveFile'; |
| 10 | +import { ActivityIndicator, Text } from 'react-native'; |
| 11 | +import type { ComponentProps } from 'react'; |
| 12 | + |
| 13 | +export interface RiveViewProps |
| 14 | + extends Omit<ComponentProps<typeof NitroRiveView>, 'file'> { |
| 15 | + /** Name of the artboard to display from the Rive file */ |
| 16 | + artboardName?: string; |
| 17 | + /** Name of the state machine to play */ |
| 18 | + stateMachineName?: string; |
| 19 | + /** Whether to automatically bind the state machine and artboard */ |
| 20 | + autoBind?: boolean; |
| 21 | + /** Whether to automatically start playing the state machine */ |
| 22 | + autoPlay?: boolean; |
| 23 | + /** The Rive file to be displayed */ |
| 24 | + file: RiveFile | RiveFileInput; |
| 25 | + /** How the Rive graphic should be aligned within its container */ |
| 26 | + alignment?: Alignment; |
| 27 | + /** How the Rive graphic should fit within its container */ |
| 28 | + fit?: Fit; |
| 29 | + /** The scale factor to apply to the Rive graphic when using Fit.Layout */ |
| 30 | + layoutScaleFactor?: number; |
| 31 | + /** Referenced assets for out-of-band asset loading */ |
| 32 | + referencedAssets?: ReferencedAssets; |
| 33 | +} |
| 34 | + |
| 35 | +function isNitroFile(file: RiveFile | RiveFileInput): file is RiveFile { |
| 36 | + return ( |
| 37 | + typeof file === 'object' && |
| 38 | + '__type' in file && |
| 39 | + file.__type === 'HybridObject<RiveFile>' |
| 40 | + ); |
| 41 | +} |
| 42 | + |
| 43 | +function RiveViewWithFileInput( |
| 44 | + props: Omit<RiveViewProps, 'file'> & { |
| 45 | + file: RiveFileInput; |
| 46 | + referencedAssets?: ReferencedAssets; |
| 47 | + } |
| 48 | +) { |
| 49 | + const { file, referencedAssets, ...rest } = props; |
| 50 | + const { riveFile, isLoading, error } = useRiveFile(file, referencedAssets); |
| 51 | + |
| 52 | + if (isLoading) { |
| 53 | + return <ActivityIndicator />; |
| 54 | + } else if (error != null) { |
| 55 | + return <Text>{error}</Text>; |
| 56 | + } else { |
| 57 | + return <NitroRiveView {...rest} file={riveFile} />; |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +export function RiveView(props: RiveViewProps) { |
| 62 | + const { file, referencedAssets, ...rest } = props; |
| 63 | + |
| 64 | + if (isNitroFile(file)) { |
| 65 | + return <NitroRiveView {...rest} file={file} />; |
| 66 | + } else { |
| 67 | + return ( |
| 68 | + <RiveViewWithFileInput |
| 69 | + {...rest} |
| 70 | + file={file} |
| 71 | + referencedAssets={referencedAssets} |
| 72 | + /> |
| 73 | + ); |
| 74 | + } |
| 75 | +} |
0 commit comments