1 | 'use strict';
|
2 | import type { NativeSyntheticEvent } from 'react-native';
|
3 | import { registerEventHandler, unregisterEventHandler } from './core';
|
4 | import type {
|
5 | EventPayload,
|
6 | ReanimatedEvent,
|
7 | IWorkletEventHandler,
|
8 | } from './hook/commonTypes';
|
9 | import { shouldBeUseWeb } from './PlatformChecker';
|
10 |
|
11 | const SHOULD_BE_USE_WEB = shouldBeUseWeb();
|
12 |
|
13 | type JSEvent<Event extends object> = NativeSyntheticEvent<EventPayload<Event>>;
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | function jsListener<Event extends object>(
|
19 | eventName: string,
|
20 | handler: (event: ReanimatedEvent<Event>) => void
|
21 | ) {
|
22 | return (evt: JSEvent<Event>) => {
|
23 | handler({ ...evt.nativeEvent, eventName } as ReanimatedEvent<Event>);
|
24 | };
|
25 | }
|
26 |
|
27 | class WorkletEventHandlerNative<Event extends object>
|
28 | implements IWorkletEventHandler<Event>
|
29 | {
|
30 | eventNames: string[];
|
31 | worklet: (event: ReanimatedEvent<Event>) => void;
|
32 | #viewTags: Set<number>;
|
33 | #registrations: Map<number, number[]>;
|
34 | constructor(
|
35 | worklet: (event: ReanimatedEvent<Event>) => void,
|
36 | eventNames: string[]
|
37 | ) {
|
38 | this.worklet = worklet;
|
39 | this.eventNames = eventNames;
|
40 | this.#viewTags = new Set<number>();
|
41 | this.#registrations = new Map<number, number[]>();
|
42 | }
|
43 |
|
44 | updateEventHandler(
|
45 | newWorklet: (event: ReanimatedEvent<Event>) => void,
|
46 | newEvents: string[]
|
47 | ): void {
|
48 |
|
49 | this.worklet = newWorklet;
|
50 | this.eventNames = newEvents;
|
51 |
|
52 |
|
53 | this.#registrations.forEach((registrationIDs) => {
|
54 | registrationIDs.forEach((id) => unregisterEventHandler(id));
|
55 |
|
56 | });
|
57 |
|
58 |
|
59 | Array.from(this.#viewTags).forEach((tag) => {
|
60 | const newRegistrations = this.eventNames.map((eventName) =>
|
61 | registerEventHandler(this.worklet, eventName, tag)
|
62 | );
|
63 | this.#registrations.set(tag, newRegistrations);
|
64 | });
|
65 | }
|
66 |
|
67 | registerForEvents(viewTag: number, fallbackEventName?: string): void {
|
68 | this.#viewTags.add(viewTag);
|
69 |
|
70 | const newRegistrations = this.eventNames.map((eventName) =>
|
71 | registerEventHandler(this.worklet, eventName, viewTag)
|
72 | );
|
73 | this.#registrations.set(viewTag, newRegistrations);
|
74 |
|
75 | if (this.eventNames.length === 0 && fallbackEventName) {
|
76 | const newRegistration = registerEventHandler(
|
77 | this.worklet,
|
78 | fallbackEventName,
|
79 | viewTag
|
80 | );
|
81 | this.#registrations.set(viewTag, [newRegistration]);
|
82 | }
|
83 | }
|
84 |
|
85 | unregisterFromEvents(viewTag: number): void {
|
86 | this.#viewTags.delete(viewTag);
|
87 | this.#registrations.get(viewTag)?.forEach((id) => {
|
88 | unregisterEventHandler(id);
|
89 | });
|
90 | this.#registrations.delete(viewTag);
|
91 | }
|
92 | }
|
93 |
|
94 | class WorkletEventHandlerWeb<Event extends object>
|
95 | implements IWorkletEventHandler<Event>
|
96 | {
|
97 | eventNames: string[];
|
98 | listeners:
|
99 | | Record<string, (event: ReanimatedEvent<ReanimatedEvent<Event>>) => void>
|
100 | | Record<string, (event: JSEvent<Event>) => void>;
|
101 |
|
102 | worklet: (event: ReanimatedEvent<Event>) => void;
|
103 |
|
104 | constructor(
|
105 | worklet: (event: ReanimatedEvent<Event>) => void,
|
106 | eventNames: string[] = []
|
107 | ) {
|
108 | this.worklet = worklet;
|
109 | this.eventNames = eventNames;
|
110 | this.listeners = {};
|
111 | this.setupWebListeners();
|
112 | }
|
113 |
|
114 | setupWebListeners() {
|
115 | this.listeners = {};
|
116 | this.eventNames.forEach((eventName) => {
|
117 | this.listeners[eventName] = jsListener(eventName, this.worklet);
|
118 | });
|
119 | }
|
120 |
|
121 | updateEventHandler(
|
122 | newWorklet: (event: ReanimatedEvent<Event>) => void,
|
123 | newEvents: string[]
|
124 | ): void {
|
125 |
|
126 | this.worklet = newWorklet;
|
127 | this.eventNames = newEvents;
|
128 | this.setupWebListeners();
|
129 | }
|
130 |
|
131 | registerForEvents(_viewTag: number, _fallbackEventName?: string): void {
|
132 |
|
133 | }
|
134 |
|
135 | unregisterFromEvents(_viewTag: number): void {
|
136 |
|
137 | }
|
138 | }
|
139 |
|
140 | export const WorkletEventHandler = SHOULD_BE_USE_WEB
|
141 | ? WorkletEventHandlerWeb
|
142 | : WorkletEventHandlerNative;
|