1 | 'use strict';
|
2 |
|
3 | import { shallowEqual } from '../reanimated2/hook/utils';
|
4 | import type { StyleProps } from '../reanimated2/commonTypes';
|
5 | import { isSharedValue } from '../reanimated2/isSharedValue';
|
6 | import { isChromeDebugger } from '../reanimated2/PlatformChecker';
|
7 | import { WorkletEventHandler } from '../reanimated2/WorkletEventHandler';
|
8 | import { initialUpdaterRun } from '../reanimated2/animation';
|
9 | import { hasInlineStyles, getInlineStyle } from './InlinePropManager';
|
10 | import type {
|
11 | AnimatedComponentProps,
|
12 | AnimatedProps,
|
13 | InitialComponentProps,
|
14 | IAnimatedComponentInternal,
|
15 | IPropsFilter,
|
16 | } from './commonTypes';
|
17 | import { flattenArray, has } from './utils';
|
18 | import { StyleSheet } from 'react-native';
|
19 |
|
20 | function dummyListener() {
|
21 |
|
22 |
|
23 | }
|
24 |
|
25 | export class PropsFilter implements IPropsFilter {
|
26 | private _initialStyle = {};
|
27 | private _previousProps: React.Component['props'] | null = null;
|
28 | private _requiresNewInitials = true;
|
29 |
|
30 | public filterNonAnimatedProps(
|
31 | component: React.Component<unknown, unknown> & IAnimatedComponentInternal
|
32 | ): Record<string, unknown> {
|
33 | const inputProps =
|
34 | component.props as AnimatedComponentProps<InitialComponentProps>;
|
35 |
|
36 | this._maybePrepareForNewInitials(inputProps);
|
37 |
|
38 | const props: Record<string, unknown> = {};
|
39 | for (const key in inputProps) {
|
40 | const value = inputProps[key];
|
41 | if (key === 'style') {
|
42 | const styleProp = inputProps.style;
|
43 | const styles = flattenArray<StyleProps>(styleProp ?? []);
|
44 | if (this._requiresNewInitials) {
|
45 | this._initialStyle = {};
|
46 | }
|
47 | const processedStyle: StyleProps = styles.map((style) => {
|
48 | if (style && style.viewDescriptors) {
|
49 |
|
50 |
|
51 | style.viewsRef?.add(component);
|
52 | if (this._requiresNewInitials) {
|
53 | this._initialStyle = {
|
54 | ...style.initial.value,
|
55 | ...this._initialStyle,
|
56 | ...initialUpdaterRun<StyleProps>(style.initial.updater),
|
57 | };
|
58 | }
|
59 | return this._initialStyle;
|
60 | } else if (hasInlineStyles(style)) {
|
61 | return getInlineStyle(style, this._requiresNewInitials);
|
62 | } else {
|
63 | return style;
|
64 | }
|
65 | });
|
66 | props[key] = StyleSheet.flatten(processedStyle);
|
67 | } else if (key === 'animatedProps') {
|
68 | const animatedProp = inputProps.animatedProps as Partial<
|
69 | AnimatedComponentProps<AnimatedProps>
|
70 | >;
|
71 | if (animatedProp.initial !== undefined) {
|
72 | Object.keys(animatedProp.initial.value).forEach((initialValueKey) => {
|
73 | props[initialValueKey] =
|
74 | animatedProp.initial?.value[initialValueKey];
|
75 |
|
76 | animatedProp.viewsRef?.add(component);
|
77 | });
|
78 | }
|
79 | } else if (
|
80 | has('workletEventHandler', value) &&
|
81 | value.workletEventHandler instanceof WorkletEventHandler
|
82 | ) {
|
83 | if (value.workletEventHandler.eventNames.length > 0) {
|
84 | value.workletEventHandler.eventNames.forEach((eventName) => {
|
85 | props[eventName] = has('listeners', value.workletEventHandler)
|
86 | ? (
|
87 | value.workletEventHandler.listeners as Record<string, unknown>
|
88 | )[eventName]
|
89 | : dummyListener;
|
90 | });
|
91 | } else {
|
92 | props[key] = dummyListener;
|
93 | }
|
94 | } else if (isSharedValue(value)) {
|
95 | if (this._requiresNewInitials) {
|
96 | props[key] = value.value;
|
97 | }
|
98 | } else if (key !== 'onGestureHandlerStateChange' || !isChromeDebugger()) {
|
99 | props[key] = value;
|
100 | }
|
101 | }
|
102 | this._requiresNewInitials = false;
|
103 | return props;
|
104 | }
|
105 |
|
106 | private _maybePrepareForNewInitials(
|
107 | inputProps: AnimatedComponentProps<InitialComponentProps>
|
108 | ) {
|
109 | if (this._previousProps && inputProps.style) {
|
110 | this._requiresNewInitials = !shallowEqual(
|
111 | this._previousProps,
|
112 | inputProps
|
113 | );
|
114 | }
|
115 | this._previousProps = inputProps;
|
116 | }
|
117 | }
|