Skip to content

Commit d84dd0c

Browse files
committed
feat: add out of band assets
1 parent 0528f31 commit d84dd0c

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

src/Rive.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ import {
2121
RiveGeneralEvent,
2222
RiveOpenUrlEvent,
2323
RiveRendererInterface,
24+
FilesHandledMapping,
25+
RiveAssetPropType,
2426
} from './types';
2527
import { convertErrorFromNativeToRN, XOR } from './helpers';
2628

2729
import { Alignment, Fit } from './types';
30+
import { parsePossibleSources } from './utils';
2831

2932
const { RiveReactNativeRendererModule } = NativeModules;
3033

@@ -79,6 +82,7 @@ type RiveProps = {
7982
layoutScaleFactor?: number;
8083
alignment: Alignment;
8184
artboardName?: string;
85+
assetsHandled?: FilesHandledMapping;
8286
animationName?: string;
8387
stateMachineName?: string;
8488
ref: any;
@@ -104,6 +108,10 @@ type Props = {
104108
testID?: string;
105109
alignment?: Alignment;
106110
artboardName?: string;
111+
/**
112+
* @experimental This is an experimental feature and may change without a major version update (breaking change).
113+
*/
114+
assetsHandled?: FilesHandledMapping;
107115
animationName?: string;
108116
stateMachineName?: string;
109117
autoplay?: boolean;
@@ -131,6 +139,7 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
131139
fit = Fit.Contain,
132140
layoutScaleFactor,
133141
artboardName,
142+
assetsHandled: assetsHandled,
134143
animationName,
135144
stateMachineName,
136145
testID,
@@ -416,6 +425,28 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
416425
]
417426
);
418427

428+
function transformFilesHandledMapping(
429+
mapping?: FilesHandledMapping
430+
): FilesHandledMapping | undefined {
431+
const transformedMapping: FilesHandledMapping = {};
432+
if (mapping === undefined) {
433+
return undefined;
434+
}
435+
436+
Object.keys(mapping).forEach((key) => {
437+
const option = mapping[key];
438+
transformedMapping[key] = {
439+
...option,
440+
source: parsePossibleSources(option.source as RiveAssetPropType),
441+
};
442+
});
443+
444+
return transformedMapping;
445+
}
446+
447+
const convertedAssetHandledSources =
448+
transformFilesHandledMapping(assetsHandled);
449+
419450
return (
420451
<View style={[styles.container, style]} ref={ref as any} testID={testID}>
421452
<View style={styles.children}>{children}</View>
@@ -445,6 +476,7 @@ const RiveContainer = React.forwardRef<RiveRef, Props>(
445476
onError={onErrorHandler}
446477
alignment={alignment}
447478
artboardName={artboardName}
479+
assetsHandled={convertedAssetHandledSources}
448480
animationName={animationName}
449481
stateMachineName={stateMachineName}
450482
/>

src/types.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,34 @@ export interface RiveRendererInterface {
135135
androidRenderer: RiveRendererAndroid
136136
): void;
137137
}
138+
139+
export interface FileAssetSource {
140+
sourceUrl?: string;
141+
sourceAsset?: string;
142+
sourceAssetId?: string;
143+
path?: string;
144+
}
145+
146+
export interface FileHandlerOptions {
147+
source: RiveAssetPropType | FileAssetSource;
148+
}
149+
150+
export type RiveAssetPropType =
151+
| RiveAssetRequireSource
152+
| RiveAssetUriSource
153+
| RiveAssetPackagedSource;
154+
155+
export type RiveAssetRequireSource = number;
156+
157+
export interface RiveAssetUriSource {
158+
uri: string;
159+
}
160+
161+
export interface RiveAssetPackagedSource {
162+
fileName: string;
163+
path?: string; // only needed for Android assets
164+
}
165+
166+
export interface FilesHandledMapping {
167+
[assetName: string]: FileHandlerOptions;
168+
}

src/utils.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Image } from 'react-native';
2+
import type { FileAssetSource, RiveAssetPropType } from './types';
3+
4+
function parsePossibleSources(source: RiveAssetPropType): FileAssetSource {
5+
if (typeof source === 'number') {
6+
const resolvedAsset = Image.resolveAssetSource(source);
7+
console.log(resolvedAsset);
8+
if (resolvedAsset && resolvedAsset.uri) {
9+
return { sourceAssetId: resolvedAsset.uri };
10+
} else {
11+
throw new Error('Invalid asset source provided.');
12+
}
13+
}
14+
15+
const uri = (source as any).uri;
16+
if (typeof source === 'object' && uri) {
17+
return { sourceUrl: uri };
18+
}
19+
20+
const asset = (source as any).fileName;
21+
const path = (source as any).path;
22+
23+
if (typeof source === 'object' && asset) {
24+
const result: FileAssetSource = { sourceAsset: asset };
25+
26+
if (path) {
27+
result.path = path;
28+
}
29+
30+
return result;
31+
}
32+
33+
throw new Error('Invalid source provided.');
34+
}
35+
36+
export { parsePossibleSources };

0 commit comments

Comments
 (0)