@mappedin/dynamic-focus 6.0.1-beta.54 → 6.0.1-beta.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -1
- package/lib/dynamic-focus.iife.js.map +7 -0
- package/lib/esm/chunk-UUWLLGNN.js +1207 -0
- package/lib/esm/chunk-UUWLLGNN.js.map +7 -0
- package/lib/esm/index.d.ts +25 -4
- package/lib/esm/index.js +3 -11124
- package/lib/esm/index.js.map +4 -4
- package/lib/esm/react/index.d.ts +259 -0
- package/lib/esm/react/index.js +77 -0
- package/lib/esm/react/index.js.map +7 -0
- package/lib/rn/index-rn.d.ts +4 -0
- package/lib/rn/index-rn.js +278 -0
- package/lib/rn/index-rn.js.map +7 -0
- package/lib/rn/logger.d.ts +10 -0
- package/lib/rn/rn/extension-augmentation.d.ts +15 -0
- package/lib/rn/rn/extension-source.d.ts +6 -0
- package/lib/rn/rn/use-dynamic-focus-events.d.ts +20 -0
- package/lib/rn/rn/use-dynamic-focus-registration.d.ts +31 -0
- package/lib/rn/rn/use-dynamic-focus.d.ts +91 -0
- package/lib/rn/rn/utils/facade-hydration.d.ts +8 -0
- package/lib/rn/types.d.ts +100 -0
- package/package.json +40 -5
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Generated by dts-bundle v0.7.3
|
|
2
|
+
// Dependencies for this module:
|
|
3
|
+
// ../dynamic-focus/@mappedin/mappedin-js
|
|
4
|
+
// ../dynamic-focus/@packages/internal/common/extensions
|
|
5
|
+
|
|
6
|
+
declare module '@mappedin/dynamic-focus/react' {
|
|
7
|
+
export { useDynamicFocus } from '@mappedin/dynamic-focus/react/dynamic-focus/src/react/use-dynamic-focus';
|
|
8
|
+
export { useDynamicFocusEvent } from '@mappedin/dynamic-focus/react/dynamic-focus/src/react/use-dynamic-focus-event';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
declare module '@mappedin/dynamic-focus/react/dynamic-focus/src/react/use-dynamic-focus' {
|
|
12
|
+
import { DynamicFocus } from '@mappedin/dynamic-focus/react/dynamic-focus/src/dynamic-focus';
|
|
13
|
+
export function useDynamicFocus(): DynamicFocus;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare module '@mappedin/dynamic-focus/react/dynamic-focus/src/react/use-dynamic-focus-event' {
|
|
17
|
+
import type { DynamicFocusEvents } from '@mappedin/dynamic-focus/react/dynamic-focus/src/types';
|
|
18
|
+
export function useDynamicFocusEvent<T extends keyof DynamicFocusEvents>(event: T, callback: (event: DynamicFocusEvents[T]) => void): void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare module '@mappedin/dynamic-focus/react/dynamic-focus/src/dynamic-focus' {
|
|
22
|
+
import type { Facade, FloorStack, MapView } from '@mappedin/mappedin-js';
|
|
23
|
+
import { Floor } from '@mappedin/mappedin-js';
|
|
24
|
+
import type { DynamicFocusEventPayload, DynamicFocusEvents, DynamicFocusState } from '@mappedin/dynamic-focus/react/dynamic-focus/src/types';
|
|
25
|
+
import type { MapViewExtension } from '@packages/internal/common/extensions';
|
|
26
|
+
/**
|
|
27
|
+
* Dynamic Focus is a MapView scene manager that maintains the visibility of the outdoors
|
|
28
|
+
* while fading in and out building interiors as the camera pans.
|
|
29
|
+
*/
|
|
30
|
+
export class DynamicFocus implements MapViewExtension<DynamicFocusState> {
|
|
31
|
+
#private;
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new instance of the Dynamic Focus controller.
|
|
34
|
+
*
|
|
35
|
+
* @param mapView - The {@link MapView} to attach Dynamic Focus to.
|
|
36
|
+
* @param options - Options for configuring Dynamic Focus.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const mapView = show3dMap(...);
|
|
41
|
+
* const df = new DynamicFocus(mapView);
|
|
42
|
+
* df.enable({ autoFocus: true });
|
|
43
|
+
*
|
|
44
|
+
* // pause the listener
|
|
45
|
+
* df.updateState({ autoFocus: false });
|
|
46
|
+
*
|
|
47
|
+
* // manually trigger a focus
|
|
48
|
+
* df.focus();
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
constructor(mapView: MapView);
|
|
52
|
+
/**
|
|
53
|
+
* Enables Dynamic Focus with the given options.
|
|
54
|
+
* @param options - The options to enable Dynamic Focus with.
|
|
55
|
+
*/
|
|
56
|
+
enable(options?: Partial<DynamicFocusState>): void;
|
|
57
|
+
/**
|
|
58
|
+
* Disables Dynamic Focus and returns the MapView to it's previous state.
|
|
59
|
+
*/
|
|
60
|
+
disable(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Returns true if Dynamic Focus is enabled.
|
|
63
|
+
*/
|
|
64
|
+
get isEnabled(): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Returns true if the current view state is indoor.
|
|
67
|
+
*/
|
|
68
|
+
get isIndoor(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Returns true if the current view state is outdoor.
|
|
71
|
+
*/
|
|
72
|
+
get isOutdoor(): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Sets the view state to indoor, regardless of the current zoom level.
|
|
75
|
+
*/
|
|
76
|
+
setIndoor(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Sets the view state to outdoor, regardless of the current zoom level.
|
|
79
|
+
*/
|
|
80
|
+
setOutdoor(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Returns the facades that are currently in focus.
|
|
83
|
+
*/
|
|
84
|
+
get focusedFacades(): Facade[];
|
|
85
|
+
/**
|
|
86
|
+
* Subscribe to a Dynamic Focus event.
|
|
87
|
+
*/
|
|
88
|
+
on: <EventName extends keyof DynamicFocusEvents>(eventName: EventName, fn: (payload: DynamicFocusEventPayload<EventName>) => void) => void;
|
|
89
|
+
/**
|
|
90
|
+
* Unsubscribe from a Dynamic Focus event.
|
|
91
|
+
*/
|
|
92
|
+
off: <EventName extends keyof DynamicFocusEvents>(eventName: EventName, fn: (payload: DynamicFocusEventPayload<EventName>) => void) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Returns the current state of the Dynamic Focus controller.
|
|
95
|
+
*/
|
|
96
|
+
getState(): DynamicFocusState;
|
|
97
|
+
/**
|
|
98
|
+
* Updates the state of the Dynamic Focus controller.
|
|
99
|
+
* @param state - The state to update.
|
|
100
|
+
*/
|
|
101
|
+
updateState(state: Partial<DynamicFocusState>): void;
|
|
102
|
+
/**
|
|
103
|
+
* Destroys the Dynamic Focus instance and unsubscribes all MapView event listeners.
|
|
104
|
+
*/
|
|
105
|
+
destroy(): void;
|
|
106
|
+
/**
|
|
107
|
+
* Perform a manual visual update of the focused facades, and optionally set the floor.
|
|
108
|
+
* @param setFloor - Whether to set the floor. This will default to the current state of setFloorOnFocus.
|
|
109
|
+
*/
|
|
110
|
+
focus(setFloor?: boolean): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Preloads the initial floors for each building to improve performance when rendering the building for the first time. See {@link DynamicFocusState.preloadFloors}.
|
|
113
|
+
*/
|
|
114
|
+
preloadFloors(): void;
|
|
115
|
+
/**
|
|
116
|
+
* Sets the default floor for a floor stack. This is the floor that will be shown when focusing on a facade if there is no currently active floor in the stack.
|
|
117
|
+
* See {@link resetDefaultFloorForStack} to reset the default floor.
|
|
118
|
+
* @param floorStack - The floor stack to set the default floor for.
|
|
119
|
+
* @param floor - The floor to set as the default floor.
|
|
120
|
+
*/
|
|
121
|
+
setDefaultFloorForStack(floorStack: FloorStack, floor: Floor): void;
|
|
122
|
+
/**
|
|
123
|
+
* Resets the default floor for a floor stack to it's initial value.
|
|
124
|
+
* @param floorStack - The floor stack to reset the default floor for.
|
|
125
|
+
*/
|
|
126
|
+
resetDefaultFloorForStack(floorStack: FloorStack): void;
|
|
127
|
+
/**
|
|
128
|
+
* Returns the current default floor for a floor stack.
|
|
129
|
+
* @param floorStack - The floor stack to get the default floor for.
|
|
130
|
+
* @returns The current default floor for the floor stack.
|
|
131
|
+
*/
|
|
132
|
+
getDefaultFloorForStack(floorStack: FloorStack): Floor;
|
|
133
|
+
/**
|
|
134
|
+
* Sets the current floor for a floor stack. If the floor stack is currently focused, this floor will become visible.
|
|
135
|
+
* @param floorStack - The floor stack to set the current floor for.
|
|
136
|
+
*/
|
|
137
|
+
setCurrentFloorForStack(floorStack: FloorStack, floor: Floor): void;
|
|
138
|
+
/**
|
|
139
|
+
* Excludes a floor stack from visibility changes.
|
|
140
|
+
* @param excluded - The floor stack or stacks to exclude.
|
|
141
|
+
*/
|
|
142
|
+
exclude(excluded: FloorStack | FloorStack[]): void;
|
|
143
|
+
/**
|
|
144
|
+
* Includes a floor stack in visibility changes.
|
|
145
|
+
* @param included - The floor stack or stacks to include.
|
|
146
|
+
*/
|
|
147
|
+
include(included: FloorStack | FloorStack[]): void;
|
|
148
|
+
/**
|
|
149
|
+
* Returns the current floor for a floor stack.
|
|
150
|
+
* @param floorStack - The floor stack to get the current floor for.
|
|
151
|
+
* @returns The current floor for the floor stack.
|
|
152
|
+
*/
|
|
153
|
+
getCurrentFloorForStack(floorStack: FloorStack): Floor;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
declare module '@mappedin/dynamic-focus/react/dynamic-focus/src/types' {
|
|
158
|
+
import type { Facade, TFacadeState, VisibilityState as BuildingFloorStackState } from '@mappedin/mappedin-js';
|
|
159
|
+
export type DynamicFocusAnimationOptions = {
|
|
160
|
+
/**
|
|
161
|
+
* The duration of the animation in milliseconds.
|
|
162
|
+
* @default 150
|
|
163
|
+
*/
|
|
164
|
+
duration: number;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Array of valid dynamic focus modes for runtime validation.
|
|
168
|
+
*/
|
|
169
|
+
export const DYNAMIC_FOCUS_MODES: readonly ["default-floor", "lock-elevation", "nearest-elevation"];
|
|
170
|
+
/**
|
|
171
|
+
* The mode which determines the indoor floor to reveal when the camera focuses on a facade.
|
|
172
|
+
* - 'default-floor' - Show the default floor of the floor stack.
|
|
173
|
+
* - 'lock-elevation' - Show the floor at the current elevation, if possible.
|
|
174
|
+
* When a floor stack does not have a floor at the current elevation, no indoor floor will be shown.
|
|
175
|
+
* - 'nearest-elevation' - Show the floor at the current elevation, if possible.
|
|
176
|
+
* When a floor stack does not have a floor at the current elevation, show the indoor floor at the nearest lower elevation.
|
|
177
|
+
*/
|
|
178
|
+
export type DynamicFocusMode = (typeof DYNAMIC_FOCUS_MODES)[number];
|
|
179
|
+
/**
|
|
180
|
+
* State of the Dynamic Focus controller.
|
|
181
|
+
*/
|
|
182
|
+
export type DynamicFocusState = {
|
|
183
|
+
/**
|
|
184
|
+
* Whether to automatically focus on the outdoors when the camera moves in range.
|
|
185
|
+
* @default true
|
|
186
|
+
*/
|
|
187
|
+
autoFocus: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* The zoom level at which the camera will fade out the facades and fade in the indoor floors.
|
|
190
|
+
* @default 18
|
|
191
|
+
*/
|
|
192
|
+
indoorZoomThreshold: number;
|
|
193
|
+
/**
|
|
194
|
+
* The zoom level at which the camera will fade in the facades and fade out the indoor floors.
|
|
195
|
+
* @default 17
|
|
196
|
+
*/
|
|
197
|
+
outdoorZoomThreshold: number;
|
|
198
|
+
/**
|
|
199
|
+
* Whether to set the floor to the outdoors when the camera moves in range.
|
|
200
|
+
* @default true
|
|
201
|
+
*/
|
|
202
|
+
setFloorOnFocus: boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Options for the animation when fading out the facade to reveal the interior.
|
|
205
|
+
*/
|
|
206
|
+
indoorAnimationOptions: DynamicFocusAnimationOptions;
|
|
207
|
+
/**
|
|
208
|
+
* Options for the animation when fading in the facade to hide the interior.
|
|
209
|
+
*/
|
|
210
|
+
outdoorAnimationOptions: DynamicFocusAnimationOptions;
|
|
211
|
+
/**
|
|
212
|
+
* The mode of the Dynamic Focus controller.
|
|
213
|
+
* @default 'default-floor'
|
|
214
|
+
*/
|
|
215
|
+
mode: DynamicFocusMode;
|
|
216
|
+
/**
|
|
217
|
+
* Whether to automatically adjust facade heights to align with floor boundaries in multi-floor buildings.
|
|
218
|
+
* @default false
|
|
219
|
+
*/
|
|
220
|
+
autoAdjustFacadeHeights: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* Whether to preload the geometry of the initial floors in each building. Improves performance when rendering the building for the first time.
|
|
223
|
+
* @default true
|
|
224
|
+
*/
|
|
225
|
+
preloadFloors: boolean;
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Internal events emitted for updating React state.
|
|
229
|
+
*/
|
|
230
|
+
export type InternalDynamicFocusEvents = {
|
|
231
|
+
'state-change': undefined;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Events emitted by the Dynamic Focus controller.
|
|
235
|
+
*/
|
|
236
|
+
export type DynamicFocusEvents = {
|
|
237
|
+
/**
|
|
238
|
+
* Emitted when the Dynamic Focus controller triggers a focus update either from a camera change or manually calling `focus()`.
|
|
239
|
+
*/
|
|
240
|
+
focus: {
|
|
241
|
+
facades: Facade[];
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
export type DynamicFocusEventPayload<EventName extends keyof DynamicFocusEvents> = DynamicFocusEvents[EventName] extends {
|
|
245
|
+
data: null;
|
|
246
|
+
} ? DynamicFocusEvents[EventName]['data'] : DynamicFocusEvents[EventName];
|
|
247
|
+
export type BuildingFacadeState = {
|
|
248
|
+
facade: Facade;
|
|
249
|
+
state: TFacadeState;
|
|
250
|
+
};
|
|
251
|
+
export type BuildingState = BuildingFloorStackState & {
|
|
252
|
+
facadeState: BuildingFacadeState;
|
|
253
|
+
};
|
|
254
|
+
export type ZoomState = 'in-range' | 'out-of-range' | 'transition';
|
|
255
|
+
export type ViewState = 'indoor' | 'outdoor' | 'transition';
|
|
256
|
+
export type BuildingAnimation = 'indoor' | 'outdoor' | 'none';
|
|
257
|
+
export type { BuildingFloorStackState };
|
|
258
|
+
}
|
|
259
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DynamicFocus,
|
|
3
|
+
__name
|
|
4
|
+
} from "../chunk-UUWLLGNN.js";
|
|
5
|
+
|
|
6
|
+
// src/react/use-dynamic-focus.ts
|
|
7
|
+
import { useCallback, useState, useMemo } from "react";
|
|
8
|
+
import { useMap, useMapViewExtension } from "@mappedin/react-sdk";
|
|
9
|
+
function useForceUpdate() {
|
|
10
|
+
const [, setState] = useState({});
|
|
11
|
+
return useCallback(() => setState({}), []);
|
|
12
|
+
}
|
|
13
|
+
__name(useForceUpdate, "useForceUpdate");
|
|
14
|
+
function useDynamicFocus() {
|
|
15
|
+
const { mapView } = useMap();
|
|
16
|
+
const forceUpdate = useForceUpdate();
|
|
17
|
+
const { register } = useMapViewExtension("dynamic-focus", {
|
|
18
|
+
onRegister: /* @__PURE__ */ __name(() => {
|
|
19
|
+
const df = new DynamicFocus(mapView);
|
|
20
|
+
df.on("state-change", forceUpdate);
|
|
21
|
+
return df;
|
|
22
|
+
}, "onRegister"),
|
|
23
|
+
onDeregister: /* @__PURE__ */ __name((df) => {
|
|
24
|
+
df.off("state-change", forceUpdate);
|
|
25
|
+
df.destroy();
|
|
26
|
+
}, "onDeregister")
|
|
27
|
+
});
|
|
28
|
+
const dynamicFocus = register();
|
|
29
|
+
if (!dynamicFocus) {
|
|
30
|
+
throw new Error("DynamicFocus is not initialized");
|
|
31
|
+
}
|
|
32
|
+
return useMemo(() => {
|
|
33
|
+
const boundFunctions = /* @__PURE__ */ new WeakMap();
|
|
34
|
+
return new Proxy(dynamicFocus, {
|
|
35
|
+
get(target, prop) {
|
|
36
|
+
const value = target[prop];
|
|
37
|
+
if (typeof value === "function") {
|
|
38
|
+
if (!boundFunctions.has(value)) {
|
|
39
|
+
boundFunctions.set(value, value.bind(target));
|
|
40
|
+
}
|
|
41
|
+
return boundFunctions.get(value);
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}, [dynamicFocus]);
|
|
47
|
+
}
|
|
48
|
+
__name(useDynamicFocus, "useDynamicFocus");
|
|
49
|
+
|
|
50
|
+
// src/react/use-dynamic-focus-event.ts
|
|
51
|
+
import { useCallback as useCallback2, useEffect, useRef } from "react";
|
|
52
|
+
function useDynamicFocusEvent(event, callback) {
|
|
53
|
+
const instance = useDynamicFocus();
|
|
54
|
+
const callbackRef = useRef(callback);
|
|
55
|
+
callbackRef.current = callback;
|
|
56
|
+
const handleCallback = useCallback2((payload) => {
|
|
57
|
+
callbackRef.current(payload);
|
|
58
|
+
}, []);
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (instance == null) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
instance.on(event, handleCallback);
|
|
64
|
+
return () => {
|
|
65
|
+
if (instance == null) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
instance.off(event, handleCallback);
|
|
69
|
+
};
|
|
70
|
+
}, [instance, event, handleCallback]);
|
|
71
|
+
}
|
|
72
|
+
__name(useDynamicFocusEvent, "useDynamicFocusEvent");
|
|
73
|
+
export {
|
|
74
|
+
useDynamicFocus,
|
|
75
|
+
useDynamicFocusEvent
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/react/use-dynamic-focus.ts", "../../../src/react/use-dynamic-focus-event.ts"],
|
|
4
|
+
"sourcesContent": ["import { useCallback, useState, useMemo } from 'react';\nimport { DynamicFocus } from '../dynamic-focus';\nimport { useMap, useMapViewExtension } from '@mappedin/react-sdk';\n\n/**\n * Simple hook to force a re-render when the returned function is called\n */\nfunction useForceUpdate() {\n\tconst [, setState] = useState({});\n\treturn useCallback(() => setState({}), []);\n}\n\nexport function useDynamicFocus(): DynamicFocus {\n\tconst { mapView } = useMap();\n\n\t// Force a re-render on dynamic focus state change to sync it up with react render cycle\n\t// The benefit of this is that dynamic focus states like isIndoor or isOutdoor changing will update the react component\n\tconst forceUpdate = useForceUpdate();\n\n\t// Register or retrieve the existing instance from the extension registry\n\tconst { register } = useMapViewExtension('dynamic-focus', {\n\t\tonRegister: () => {\n\t\t\tconst df = new DynamicFocus(mapView);\n\t\t\tdf.on('state-change' as any, forceUpdate);\n\t\t\treturn df;\n\t\t},\n\t\tonDeregister: df => {\n\t\t\tdf.off('state-change' as any, forceUpdate);\n\t\t\tdf.destroy();\n\t\t},\n\t});\n\tconst dynamicFocus = register();\n\n\tif (!dynamicFocus) {\n\t\t// We should never reach this error, but if we do something went really wrong\n\t\tthrow new Error('DynamicFocus is not initialized');\n\t}\n\n\t// Create a stable proxy using useMemo - only recreates when dynamicFocus changes\n\treturn useMemo(() => {\n\t\tconst boundFunctions = new WeakMap<object, unknown>();\n\n\t\treturn new Proxy(dynamicFocus, {\n\t\t\tget(target, prop) {\n\t\t\t\tconst value = target[prop as keyof DynamicFocus];\n\t\t\t\tif (typeof value === 'function') {\n\t\t\t\t\t// Cache bound functions by original function reference\n\t\t\t\t\tif (!boundFunctions.has(value)) {\n\t\t\t\t\t\tboundFunctions.set(value, value.bind(target));\n\t\t\t\t\t}\n\t\t\t\t\treturn boundFunctions.get(value);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t},\n\t\t});\n\t}, [dynamicFocus]);\n}\n", "import { useCallback, useEffect, useRef } from 'react';\nimport type { DynamicFocusEvents } from '../types';\nimport { useDynamicFocus } from './use-dynamic-focus';\n\nexport function useDynamicFocusEvent<T extends keyof DynamicFocusEvents>(\n\tevent: T,\n\tcallback: (event: DynamicFocusEvents[T]) => void,\n) {\n\t// this may create a new instance of dynamic focus if the developer hasn't yet\n\t// but it will not be enabled until the developer calls enable()\n\tconst instance = useDynamicFocus();\n\tconst callbackRef = useRef(callback);\n\tcallbackRef.current = callback;\n\n\tconst handleCallback = useCallback(payload => {\n\t\tcallbackRef.current(payload);\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (instance == null) {\n\t\t\treturn;\n\t\t}\n\n\t\tinstance.on(event, handleCallback);\n\n\t\treturn () => {\n\t\t\tif (instance == null) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinstance.off(event, handleCallback);\n\t\t};\n\t}, [instance, event, handleCallback]);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;AAAA,SAAS,aAAa,UAAU,eAAe;AAE/C,SAAS,QAAQ,2BAA2B;AAK5C,SAAS,iBAAiB;AACzB,QAAM,CAAC,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC;AAChC,SAAO,YAAY,MAAM,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC;AAC1C;AAHS;AAKF,SAAS,kBAAgC;AAC/C,QAAM,EAAE,QAAQ,IAAI,OAAO;AAI3B,QAAM,cAAc,eAAe;AAGnC,QAAM,EAAE,SAAS,IAAI,oBAAoB,iBAAiB;AAAA,IACzD,YAAY,6BAAM;AACjB,YAAM,KAAK,IAAI,aAAa,OAAO;AACnC,SAAG,GAAG,gBAAuB,WAAW;AACxC,aAAO;AAAA,IACR,GAJY;AAAA,IAKZ,cAAc,+BAAM;AACnB,SAAG,IAAI,gBAAuB,WAAW;AACzC,SAAG,QAAQ;AAAA,IACZ,GAHc;AAAA,EAIf,CAAC;AACD,QAAM,eAAe,SAAS;AAE9B,MAAI,CAAC,cAAc;AAElB,UAAM,IAAI,MAAM,iCAAiC;AAAA,EAClD;AAGA,SAAO,QAAQ,MAAM;AACpB,UAAM,iBAAiB,oBAAI,QAAyB;AAEpD,WAAO,IAAI,MAAM,cAAc;AAAA,MAC9B,IAAI,QAAQ,MAAM;AACjB,cAAM,QAAQ,OAAO,IAA0B;AAC/C,YAAI,OAAO,UAAU,YAAY;AAEhC,cAAI,CAAC,eAAe,IAAI,KAAK,GAAG;AAC/B,2BAAe,IAAI,OAAO,MAAM,KAAK,MAAM,CAAC;AAAA,UAC7C;AACA,iBAAO,eAAe,IAAI,KAAK;AAAA,QAChC;AACA,eAAO;AAAA,MACR;AAAA,IACD,CAAC;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAClB;AA5CgB;;;ACZhB,SAAS,eAAAA,cAAa,WAAW,cAAc;AAIxC,SAAS,qBACf,OACA,UACC;AAGD,QAAM,WAAW,gBAAgB;AACjC,QAAM,cAAc,OAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,QAAM,iBAAiBC,aAAY,aAAW;AAC7C,gBAAY,QAAQ,OAAO;AAAA,EAC5B,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACf,QAAI,YAAY,MAAM;AACrB;AAAA,IACD;AAEA,aAAS,GAAG,OAAO,cAAc;AAEjC,WAAO,MAAM;AACZ,UAAI,YAAY,MAAM;AACrB;AAAA,MACD;AACA,eAAS,IAAI,OAAO,cAAc;AAAA,IACnC;AAAA,EACD,GAAG,CAAC,UAAU,OAAO,cAAc,CAAC;AACrC;AA5BgB;",
|
|
6
|
+
"names": ["useCallback", "useCallback"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/rn/use-dynamic-focus.ts
|
|
5
|
+
import { useState, useCallback as useCallback2, useContext as useContext2, useRef } from "react";
|
|
6
|
+
import { MappedinContext as MappedinContext2 } from "@mappedin/react-native-sdk";
|
|
7
|
+
|
|
8
|
+
// src/rn/use-dynamic-focus-events.ts
|
|
9
|
+
import { useCallback, useContext } from "react";
|
|
10
|
+
|
|
11
|
+
// ../packages/common/Mappedin.Logger.ts
|
|
12
|
+
var MI_ERROR_LABEL = "[MappedinJS]";
|
|
13
|
+
function createLogger(name = "", { prefix = MI_ERROR_LABEL } = {}) {
|
|
14
|
+
const label = `${prefix}${name ? `-${name}` : ""}`;
|
|
15
|
+
const rnDebug = /* @__PURE__ */ __name((type, args) => {
|
|
16
|
+
if (typeof window !== "undefined" && window.rnDebug) {
|
|
17
|
+
const processed = args.map((arg) => {
|
|
18
|
+
if (arg instanceof Error && arg.stack) {
|
|
19
|
+
return `${arg.message}
|
|
20
|
+
${arg.stack}`;
|
|
21
|
+
}
|
|
22
|
+
return arg;
|
|
23
|
+
});
|
|
24
|
+
window.rnDebug(`${name} ${type}: ${processed.join(" ")}`);
|
|
25
|
+
}
|
|
26
|
+
}, "rnDebug");
|
|
27
|
+
return {
|
|
28
|
+
logState: false ? 3 /* SILENT */ : 0 /* LOG */,
|
|
29
|
+
log(...args) {
|
|
30
|
+
if (this.logState <= 0 /* LOG */) {
|
|
31
|
+
console.log(label, ...args);
|
|
32
|
+
rnDebug("log", args);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
warn(...args) {
|
|
36
|
+
if (this.logState <= 1 /* WARN */) {
|
|
37
|
+
console.warn(label, ...args);
|
|
38
|
+
rnDebug("warn", args);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
error(...args) {
|
|
42
|
+
if (this.logState <= 2 /* ERROR */) {
|
|
43
|
+
console.error(label, ...args);
|
|
44
|
+
rnDebug("error", args);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
// It's a bit tricky to prepend [MappedinJs] to assert and time because of how the output is structured in the console, so it is left out for simplicity
|
|
48
|
+
assert(...args) {
|
|
49
|
+
console.assert(...args);
|
|
50
|
+
},
|
|
51
|
+
time(label2) {
|
|
52
|
+
console.time(label2);
|
|
53
|
+
},
|
|
54
|
+
timeEnd(label2) {
|
|
55
|
+
console.timeEnd(label2);
|
|
56
|
+
},
|
|
57
|
+
setLevel(level) {
|
|
58
|
+
if (0 /* LOG */ <= level && level <= 3 /* SILENT */) {
|
|
59
|
+
this.logState = level;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
__name(createLogger, "createLogger");
|
|
65
|
+
var Logger = createLogger();
|
|
66
|
+
|
|
67
|
+
// src/logger.ts
|
|
68
|
+
var Logger2 = createLogger("", { prefix: "[DynamicFocus]" });
|
|
69
|
+
|
|
70
|
+
// src/rn/use-dynamic-focus-events.ts
|
|
71
|
+
import {
|
|
72
|
+
MappedinContext,
|
|
73
|
+
useEventCallback,
|
|
74
|
+
createEventSetupScript,
|
|
75
|
+
createEventCleanupScript
|
|
76
|
+
} from "@mappedin/react-native-sdk";
|
|
77
|
+
|
|
78
|
+
// src/rn/utils/facade-hydration.ts
|
|
79
|
+
function hydrateFacades(mapData, facades) {
|
|
80
|
+
return facades.map((facadeData) => {
|
|
81
|
+
if (facadeData && facadeData.id) {
|
|
82
|
+
const hydratedFacade = mapData.getById("facade", facadeData.id);
|
|
83
|
+
return hydratedFacade || facadeData;
|
|
84
|
+
}
|
|
85
|
+
return facadeData;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
__name(hydrateFacades, "hydrateFacades");
|
|
89
|
+
|
|
90
|
+
// src/rn/use-dynamic-focus-registration.ts
|
|
91
|
+
import { useRegisterExtension } from "@mappedin/react-native-sdk";
|
|
92
|
+
|
|
93
|
+
// src/rn/extension-source.ts
|
|
94
|
+
var EXTENSION_SOURCE_PLACEHOLDER = `
|
|
95
|
+
// Define require function that uses bridge.modules for external dependencies
|
|
96
|
+
globalThis.require = globalThis.require || ((id) => {
|
|
97
|
+
if (window.bridge?.modules?.[id]) {
|
|
98
|
+
return window.bridge.modules[id];
|
|
99
|
+
}
|
|
100
|
+
throw new Error('Module not found: ' + id);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
"use strict";var DynamicFocus=(()=>{var J=Object.defineProperty;var Yt=Object.getOwnPropertyDescriptor;var \$t=Object.getOwnPropertyNames;var Ht=Object.prototype.hasOwnProperty;var xt=a=>{throw TypeError(a)};var qt=(a,t,e)=>t in a?J(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var n=(a,t)=>J(a,"name",{value:t,configurable:!0}),rt=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});var Wt=(a,t)=>{for(var e in t)J(a,e,{get:t[e],enumerable:!0})},Kt=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of \$t(t))!Ht.call(a,s)&&s!==e&&J(a,s,{get:()=>t[s],enumerable:!(i=Yt(t,s))||i.enumerable});return a};var zt=a=>Kt(J({},"__esModule",{value:!0}),a);var S=(a,t,e)=>qt(a,typeof t!="symbol"?t+"":t,e),mt=(a,t,e)=>t.has(a)||xt("Cannot "+e);var o=(a,t,e)=>(mt(a,t,"read from private field"),e?e.call(a):t.get(a)),d=(a,t,e)=>t.has(a)?xt("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(a):t.set(a,e),l=(a,t,e,i)=>(mt(a,t,"write to private field"),i?i.call(a,e):t.set(a,e),e),v=(a,t,e)=>(mt(a,t,"access private method"),e);var oo={};Wt(oo,{DynamicFocus:()=>ht});var jt=rt("@mappedin/mappedin-js");function Vt(a,t){if(a==null||t==null)return a===t;if(a.length!==t.length)return!1;for(let e=0;e<a.length;e++)if(a[e]!==t[e])return!1;return!0}n(Vt,"arraysEqual");var pt=class pt{constructor(){S(this,"_subscribers",{});S(this,"_destroyed",!1)}publish(t,e){!this._subscribers||!this._subscribers[t]||this._destroyed||this._subscribers[t].forEach(function(i){typeof i=="function"&&i(e)})}on(t,e){(!this._subscribers||this._destroyed)&&(this._subscribers={}),this._subscribers[t]=this._subscribers[t]||[],this._subscribers[t].push(e)}off(t,e){if(!this._subscribers||this._subscribers[t]==null||this._destroyed)return;let i=this._subscribers[t].indexOf(e);i!==-1&&this._subscribers[t].splice(i,1)}destroy(){this._destroyed=!0,this._subscribers={}}};n(pt,"PubSub");var nt=pt;var U=rt("@mappedin/mappedin-js");var k,X,V,y,m,E,T,j,G,Ft=class Ft{constructor(t,e){S(this,"__type","building");d(this,k);d(this,X,new Map);d(this,V,new Map);d(this,y,[]);d(this,m);d(this,E);d(this,T);S(this,"defaultFloor");S(this,"activeFloor");S(this,"excluded",!1);d(this,j);d(this,G);l(this,k,t),l(this,X,new Map(t.floors.map(i=>[i.id,i]))),l(this,V,new Map(t.floors.map(i=>[i.elevation,i]))),l(this,y,Array.from(o(this,V).values()).sort((i,s)=>i.elevation-s.elevation)),this.defaultFloor=t.defaultFloor,this.activeFloor=this.defaultFloor,l(this,m,e)}get id(){return o(this,k).id}get name(){return o(this,k).name}get floors(){return o(this,k).floors}get floorStack(){return o(this,k)}get facade(){return o(this,k).facade}get isCurrentFloorStack(){return this.id===o(this,m).currentFloorStack.id}get isIndoor(){let t=o(this,m).getState(this.facade);return this.isCurrentFloorStack||t?.visible===!1&&t?.opacity===0}get canSetFloor(){return this.isIndoor||!this.excluded}get maxElevation(){return o(this,j)==null&&l(this,j,Math.max(...o(this,V).keys())),o(this,j)}get minElevation(){return o(this,G)==null&&l(this,G,Math.min(...o(this,V).keys())),o(this,G)}has(t){return U.Floor.is(t)?o(this,X).has(t.id):U.FloorStack.is(t)?t.id===o(this,k).id:U.Facade.is(t)?t.id===this.facade.id:!1}get aboveGroundFloors(){return o(this,y).filter(t=>t.elevation>=0)}expandFacade(){if(!o(this,m).options.multiFloorView?.enabled||!this.facade||this.facade.__type!=="facade"||this.facade.spaces.length<1)return;let t=o(this,m).options.multiFloorView.floorGap??10;if(!o(this,E)){l(this,E,new Map);for(let p of this.facade.spaces){let h=o(this,m).getState(p),b=h?.altitude??0,N=h?.height??0;o(this,E).has(b)||o(this,E).set(b,[]),o(this,E).get(b).push({space:p,originalAltitude:b,originalHeight:N})}}let e=Array.from(o(this,E).keys()).sort((p,h)=>p-h),i=e.length===1,s=i?t*(this.aboveGroundFloors.length-1):t,c=0;e.forEach(p=>{let h=o(this,E).get(p);for(let{space:b}of h)o(this,m).updateState(b,{height:i?s:t,altitude:c});i||(c+=t)})}collapseFacade(){if(o(this,E)){for(let t of o(this,E).values())for(let{space:e,originalAltitude:i,originalHeight:s}of t)o(this,m).updateState(e,{height:s,altitude:i});l(this,E,void 0)}}getFloorByElevation(t){return o(this,V).get(t)}getNearestFloorByElevation(t){let e=this.getFloorByElevation(t);if(e)return e;if(t>=0){if(t>this.maxElevation)return o(this,y)[o(this,y).length-1];for(let i=o(this,y).length-1;i>=0;i--){let s=o(this,y)[i];if(s.elevation<=t)return s}}else{if(t<this.minElevation)return o(this,y)[0];for(let i of o(this,y))if(i.elevation>=t)return i}}getHighestFloor(){return o(this,y)[o(this,y).length-1]}cancelAnimation(){o(this,T)&&(o(this,T).animation.cancel(),l(this,T,void 0))}async animateFacade(t,e={duration:150}){let i=o(this,T)?.state||o(this,m).getState(this.facade);if(!i||!t||i?.opacity===t.opacity&&i?.visible===t.visible)return{result:"completed"};this.cancelAnimation();let{opacity:s,visible:c}=t;if(o(this,m).updateState(this.facade,{visible:!0}),s!==void 0){l(this,T,{animation:o(this,m).animateState(this.facade,{opacity:s},{duration:e.duration}),state:t});let p=await o(this,T).animation;if(l(this,T,void 0),p.result==="cancelled")return p}return c===!1&&o(this,m).updateState(this.facade,{visible:c}),{result:"completed"}}destroy(){this.cancelAnimation(),o(this,k).floors.forEach(t=>{o(this,m).updateState(t,{visible:t.id===o(this,m).currentFloor.id})}),this.has(o(this,m).currentFloor)||o(this,m).updateState(this.facade,{visible:!0,opacity:1})}};k=new WeakMap,X=new WeakMap,V=new WeakMap,y=new WeakMap,m=new WeakMap,E=new WeakMap,T=new WeakMap,j=new WeakMap,G=new WeakMap,n(Ft,"Building");var lt=Ft;var Ot=rt("@mappedin/mappedin-js");function _t(a,t,e){return a>=t?"in-range":a<=e?"out-of-range":"transition"}n(_t,"getZoomState");function dt(a,t,e){if(a.__type==="outdoors"&&"floor"in a)return a.floor;let i=a;if(i.excluded)return i.activeFloor;switch(t){case"lock-elevation":return i.getFloorByElevation(e);case"nearest-elevation":return i.getNearestFloorByElevation(e);default:break}return i.isIndoor?i.activeFloor:i.defaultFloor}n(dt,"getFloorToShow");function Qt(a,t){return{facade:a,state:{type:"facade",visible:!t,opacity:t?0:1}}}n(Qt,"getFacadeState");function Jt(a,t,e){return{outdoorOpacity:1,floorStates:a.floors.map(i=>{let s=i.id===t.id&&e;return{floor:i,state:{type:"floor",visible:s,geometry:{visible:s},labels:{enabled:s},markers:{enabled:s},footprint:{visible:!1},occlusion:{enabled:!1}}}})}}n(Jt,"getSingleBuildingState");function Mt(a,t){if(!t.includes("lock-elevation"))return 1;for(let e of a)if(e.outdoorOpacity>=0&&e.outdoorOpacity<=1)return e.outdoorOpacity;return 1}n(Mt,"getOutdoorOpacity");function Nt(a,t,e){switch(e){case"in-range":return a[0]?.canSetFloor?a[0]:void 0;case"out-of-range":return t;case"transition":default:return}}n(Nt,"getSetFloorTargetFromZoomState");function Bt(a,t,e,i,s,c,p,h,b){let N=new Map;for(let f of a){let R=t.has(f.id),Q=gt(f,e,i==="in-range",R,s,c,h.includes(f.id)),B=e.floorStack.id===f.id?f.activeFloor:dt(f,s,c),st=b.enabled?(0,Ot.getMultiFloorState)(f.floors,B||f.activeFloor,b.floorGap,p):Jt(f.floorStack,B||f.activeFloor,Q),ft=Qt(f.facade,Q);N.set(f.id,{building:f,showIndoor:Q,floorStackState:st,facadeState:ft,inFocus:R,floorToShow:B})}return N}n(Bt,"getBuildingStates");function Lt(a,t){return a.excluded?"none":t?"indoor":"outdoor"}n(Lt,"getBuildingAnimationType");function gt(a,t,e,i,s,c,p){if(a.id===t.floorStack.id)return!0;if(a.excluded)return!1;if(p===!0)return!0;if(!e)return!1;switch(s){case"lock-elevation":return a.getFloorByElevation(c)!=null;default:break}return!!i}n(gt,"shouldShowIndoor");function It(a,t,e){return a!==t&&!e}n(It,"shouldDeferSetFloor");var Ct=["default-floor","lock-elevation","nearest-elevation"];var ut=rt("@mappedin/mappedin-js");var Xt="[MappedinJS]";function St(a="",{prefix:t=Xt}={}){let e=\`\${t}\${a?\`-\${a}\`:""}\`,i=n((s,c)=>{if(typeof window<"u"&&window.rnDebug){let p=c.map(h=>h instanceof Error&&h.stack?\`\${h.message}
|
|
104
|
+
\${h.stack}\`:h);window.rnDebug(\`\${a} \${s}: \${p.join(" ")}\`)}},"rnDebug");return{logState:0,log(...s){this.logState<=0&&(console.log(e,...s),i("log",s))},warn(...s){this.logState<=1&&(console.warn(e,...s),i("warn",s))},error(...s){this.logState<=2&&(console.error(e,...s),i("error",s))},assert(...s){console.assert(...s)},time(s){console.time(s)},timeEnd(s){console.timeEnd(s)},setLevel(s){0<=s&&s<=3&&(this.logState=s)}}}n(St,"createLogger");var to=St();var Y=to;function Zt(a,t,e,i){return(a<t||a>e)&&Y.warn(i),Math.min(e,Math.max(t,a))}n(Zt,"clampWithWarning");function yt(a,t){return!ut.Floor.is(a)||a?.floorStack==null||!ut.FloorStack.is(t)?!1:a.floorStack.id!==t.id?(Y.warn(\`Floor (\${a.id}) does not belong to floor stack (\${t.id}).\`),!1):!0}n(yt,"validateFloorForStack");function Et(a,t,e,i){return Zt(a,t,e,\`\${i} must be between \${t} and \${e}.\`)}n(Et,"validateZoomThreshold");var \$=St("",{prefix:"[DynamicFocus]"});var w,H,tt,bt,vt=class vt{constructor(t,e){d(this,tt);S(this,"__type","outdoors");d(this,w);d(this,H);l(this,w,t),l(this,H,e)}get id(){return o(this,w).id}get floorStack(){return o(this,w)}get floor(){return o(this,w).defaultFloor}matchesFloorStack(t){return t===o(this,w)||t===o(this,w).id}show(){v(this,tt,bt).call(this,!0)}hide(){v(this,tt,bt).call(this,!1)}destroy(){this.matchesFloorStack(o(this,H).currentFloorStack)||this.hide()}};w=new WeakMap,H=new WeakMap,tt=new WeakSet,bt=n(function(t){for(let e of o(this,w).floors)o(this,H).updateState(e,{visible:t})},"#setVisible"),n(vt,"Outdoors");var ct=vt;function Pt(a,t){let e=a.find(s=>s.type?.toLowerCase()==="outdoor");if(e)return e;let i=a.find(s=>s.facade==null&&!t.has(s.id));return i||(\$.warn("No good candidate for the outdoor floor stack was found. Using the first floor stack."),a[0])}n(Pt,"getOutdoorFloorStack");var Rt={indoorZoomThreshold:18,outdoorZoomThreshold:17,setFloorOnFocus:!0,autoFocus:!1,indoorAnimationOptions:{duration:150},outdoorAnimationOptions:{duration:150},autoAdjustFacadeHeights:!1,mode:"default-floor",preloadFloors:!0};var D,r,L,u,I,C,F,O,Z,P,A,q,x,_,W,M,g,kt,Dt,ot,et,it,at,K,At,Gt,Ut,z,Tt=class Tt{constructor(t){d(this,g);d(this,D);d(this,r);d(this,L);d(this,u,Rt);d(this,I,[]);d(this,C,new Set);d(this,F,new Map);d(this,O);d(this,Z,!1);d(this,P,!1);d(this,A,0);d(this,q,0);d(this,x,"transition");d(this,_,"outdoor");d(this,W,[]);d(this,M,!1);S(this,"sceneUpdateQueue",Promise.resolve());S(this,"on",n((t,e)=>{o(this,D).on(t,e)},"on"));S(this,"off",n((t,e)=>{o(this,D).off(t,e)},"off"));d(this,ot,n(t=>{if(!this.isEnabled)return;let{facades:e}=t;if(!(Vt(e,this.focusedFacades)&&o(this,_)==="transition"&&!o(this,P))){if(l(this,P,!1),l(this,I,[]),o(this,C).clear(),e.length>0)for(let i of e){let s=o(this,F).get(i.floorStack.id);s&&(o(this,C).add(s.id),o(this,I).push(s))}o(this,u).autoFocus&&this.focus()}},"#handleFacadesInViewChange"));d(this,et,n(async t=>{if(!this.isEnabled)return;let{floor:e}=t,i=o(this,F).get(e.floorStack.id);i&&(i.activeFloor=e),i?.excluded===!1&&!o(this,O).matchesFloorStack(e.floorStack)&&l(this,A,e.elevation),o(this,r).manualFloorVisibility===!0&&(t.reason!=="dynamic-focus"&&(await o(this,z).call(this,e),o(this,D).publish("focus",{facades:this.focusedFacades})),o(this,r).options.multiFloorView!=null&&o(this,r).options.multiFloorView?.enabled&&o(this,r).options.multiFloorView?.updateCameraElevationOnFloorChange&&o(this,r).Camera.elevation!==o(this,A)*(o(this,r).options.multiFloorView.floorGap??0)&&o(this,r).Camera.animateElevation(o(this,A)*(o(this,r).options.multiFloorView.floorGap??0),{duration:750,easing:"ease-in-out"}))},"#handleFloorChangeStart"));d(this,it,n(()=>{l(this,Z,!0)},"#handleUserInteractionStart"));d(this,at,n(()=>{l(this,Z,!1)},"#handleUserInteractionEnd"));d(this,K,n(t=>{if(!this.isEnabled)return;let{zoomLevel:e}=t,i=_t(e,o(this,u).indoorZoomThreshold,o(this,u).outdoorZoomThreshold);o(this,x)!==i&&(l(this,x,i),i==="in-range"?this.setIndoor():i==="out-of-range"&&this.setOutdoor())},"#handleCameraChange"));d(this,z,n(async t=>{if(o(this,r).manualFloorVisibility!==!0||!this.isEnabled)return;let e=t||o(this,r).currentFloor,i=o(this,r).options.multiFloorView,s=o(this,r).Navigation?.floors?.map(h=>h.id)||[],c=o(this,r).Navigation?.floorStacks.map(h=>h.id)||[],p=new Promise(async h=>{await this.sceneUpdateQueue;let b=Bt(Array.from(o(this,F).values()),o(this,C),e,o(this,x),o(this,u).mode,o(this,A),s,c,i),N=[];await Promise.all(Array.from(b.values()).map(async f=>{let{building:R,showIndoor:Q,floorStackState:B,facadeState:st,inFocus:ft}=f;N.push(B);let wt=Lt(R,Q);if(wt==="indoor")return v(this,g,Gt).call(this,R,B,st,ft);if(wt==="outdoor")return v(this,g,Ut).call(this,R,B,st,c)})),o(this,r).Outdoor.setOpacity(Mt(N,o(this,u).mode)),l(this,W,o(this,I).filter(f=>b.get(f.id)?.showIndoor===!0).map(f=>f.facade)),o(this,D).publish("focus",{facades:o(this,W)}),h()});return this.sceneUpdateQueue=p,p},"#applyBuildingStates"));l(this,D,new nt),l(this,r,t),\$.setLevel(Y.logState),l(this,L,o(this,r).getMapData()),l(this,A,o(this,r).currentFloor.elevation),l(this,q,o(this,r).Camera.elevation);for(let e of o(this,L).getByType("facade"))o(this,F).set(e.floorStack.id,new lt(e.floorStack,o(this,r)));l(this,O,new ct(Pt(o(this,L).getByType("floor-stack"),o(this,F)),o(this,r))),o(this,r).on("floor-change-start",o(this,et)),o(this,r).on("camera-change",o(this,K)),o(this,r).on("facades-in-view-change",o(this,ot)),o(this,r).on("user-interaction-start",o(this,it)),o(this,r).on("user-interaction-end",o(this,at))}enable(t){if(o(this,M)){\$.warn("enable() called on an already enabled Dynamic Focus instance.");return}l(this,M,!0),o(this,r).manualFloorVisibility=!0,o(this,O).show(),this.updateState({...o(this,u),...t}),o(this,K).call(this,{zoomLevel:o(this,r).Camera.zoomLevel,center:o(this,r).Camera.center,bearing:o(this,r).Camera.bearing,pitch:o(this,r).Camera.pitch}),o(this,r).Camera.updateFacadesInView()}disable(){if(!o(this,M)){\$.warn("disable() called on an already disabled Dynamic Focus instance.");return}l(this,M,!1),o(this,r).manualFloorVisibility=!1}get isEnabled(){return o(this,M)}get isIndoor(){return o(this,_)==="indoor"}get isOutdoor(){return o(this,_)==="outdoor"}setIndoor(){l(this,_,"indoor"),l(this,x,"in-range"),v(this,g,kt).call(this)}setOutdoor(){l(this,_,"outdoor"),l(this,x,"out-of-range"),v(this,g,kt).call(this)}get focusedFacades(){return[...o(this,W)]}getState(){return{...o(this,u)}}updateState(t){t.indoorZoomThreshold!=null&&(t.indoorZoomThreshold=Et(t.indoorZoomThreshold,o(this,u).outdoorZoomThreshold,o(this,r).Camera.maxZoomLevel,"indoorZoomThreshold")),t.outdoorZoomThreshold!=null&&(t.outdoorZoomThreshold=Et(t.outdoorZoomThreshold,o(this,r).Camera.minZoomLevel,o(this,u).indoorZoomThreshold,"outdoorZoomThreshold")),t.mode!=null&&(t.mode=Ct.includes(t.mode)?t.mode:"default-floor"),t.autoAdjustFacadeHeights!=null&&(o(this,u).autoAdjustFacadeHeights=t.autoAdjustFacadeHeights,o(this,F).forEach(e=>{o(this,u).autoAdjustFacadeHeights?e.expandFacade():e.collapseFacade()})),l(this,u,Object.assign({},o(this,u),Object.fromEntries(Object.entries(t).filter(([,e])=>e!=null)))),t.mode!=null&&t.preloadFloors&&v(this,g,Dt).call(this,t.mode)}destroy(){this.disable(),o(this,r).off("facades-in-view-change",o(this,ot)),o(this,r).off("floor-change-start",o(this,et)),o(this,r).off("camera-change",o(this,K)),o(this,r).off("user-interaction-start",o(this,it)),o(this,r).off("user-interaction-end",o(this,at)),o(this,F).forEach(t=>t.destroy()),o(this,O).destroy(),o(this,D).destroy()}async focus(t=o(this,u).setFloorOnFocus){if(t)if(It(o(this,q),o(this,r).Camera.elevation,o(this,Z)))l(this,q,o(this,r).Camera.elevation),l(this,P,!0);else{let e=Nt(o(this,I),o(this,O),o(this,x)),i=e?dt(e,o(this,u).mode,o(this,A)):void 0;i&&i.id!==o(this,r).currentFloor.id&&o(this,r).setFloor(i,{context:"dynamic-focus"})}await o(this,z).call(this),o(this,D).publish("focus",{facades:this.focusedFacades})}preloadFloors(){v(this,g,Dt).call(this,o(this,u).mode)}setDefaultFloorForStack(t,e){if(!yt(e,t))return;let i=o(this,F).get(t.id);i&&(i.defaultFloor=e)}resetDefaultFloorForStack(t){let e=o(this,F).get(t.id);e&&(e.defaultFloor=t.defaultFloor)}getDefaultFloorForStack(t){return o(this,F).get(t.id)?.defaultFloor||t.defaultFloor||t.floors[0]}setCurrentFloorForStack(t,e){if(!yt(e,t))return;let i=o(this,F).get(t.id);i&&(i.activeFloor=e,o(this,z).call(this))}exclude(t){let e=Array.isArray(t)?t:[t];for(let i of e){let s=o(this,F).get(i.id);s&&(s.excluded=!0)}}include(t){let e=Array.isArray(t)?t:[t];for(let i of e){let s=o(this,F).get(i.id);s&&(s.excluded=!1)}}getCurrentFloorForStack(t){return o(this,F).get(t.id)?.activeFloor||this.getDefaultFloorForStack(t)}};D=new WeakMap,r=new WeakMap,L=new WeakMap,u=new WeakMap,I=new WeakMap,C=new WeakMap,F=new WeakMap,O=new WeakMap,Z=new WeakMap,P=new WeakMap,A=new WeakMap,q=new WeakMap,x=new WeakMap,_=new WeakMap,W=new WeakMap,M=new WeakMap,g=new WeakSet,kt=n(function(){o(this,u).autoFocus&&(o(this,Z)?this.focus():l(this,P,!0)),o(this,D).publish("state-change")},"#handleViewStateChange"),Dt=n(function(t){o(this,r).preloadFloors(o(this,L).getByType("facade").map(e=>dt(o(this,F).get(e.floorStack.id),t,o(this,A))).filter(e=>e!=null&&jt.Floor.is(e)))},"#preloadFloors"),ot=new WeakMap,et=new WeakMap,it=new WeakMap,at=new WeakMap,K=new WeakMap,At=n(function(t,e,i){t.forEach(s=>{if(s.floor)if(e){let c=i!==void 0?{...s.state,labels:{...s.state.labels,enabled:s.state.labels.enabled&&i},markers:{...s.state.markers,enabled:s.state.markers.enabled&&i},occlusion:{...s.state.occlusion,enabled:s.state.occlusion.enabled&&i}}:s.state;o(this,r).updateState(s.floor,c)}else o(this,r).updateState(s.floor,{visible:!1})})},"#updateFloorVisibility"),Gt=n(async function(t,e,i,s){return v(this,g,At).call(this,e.floorStates,!0,s),t.animateFacade(i.state,o(this,u).indoorAnimationOptions)},"#animateIndoorSequence"),Ut=n(async function(t,e,i,s){let c=await t.animateFacade(i.state,o(this,u).outdoorAnimationOptions);return c.result==="completed"&&v(this,g,At).call(this,e.floorStates,gt(t,o(this,r).currentFloor,o(this,x)==="in-range",o(this,C).has(t.id),o(this,u).mode,o(this,A),s.includes(t.floorStack.id))),c},"#animateOutdoorSequence"),z=new WeakMap,n(Tt,"DynamicFocus");var ht=Tt;return zt(oo);})();
|
|
105
|
+
//# sourceMappingURL=dynamic-focus.iife.js.map
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
// Register the extension
|
|
109
|
+
if (window.bridge && window.bridge.extensions) {
|
|
110
|
+
try {
|
|
111
|
+
window.bridge.extensions.register({ name: 'dynamic-focus', package: { Extension: DynamicFocus.DynamicFocus } });
|
|
112
|
+
if (window.rnDebug) window.rnDebug('Extension: dynamic-focus registered');
|
|
113
|
+
} catch(e) {
|
|
114
|
+
if (window.rnDebug) window.rnDebug('Failed to register dynamic-focus extension: ' + e.message);
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
if (window.rnDebug) window.rnDebug('Bridge or extensions not available for registration');
|
|
118
|
+
}`;
|
|
119
|
+
function getRegistrationScript() {
|
|
120
|
+
return EXTENSION_SOURCE_PLACEHOLDER;
|
|
121
|
+
}
|
|
122
|
+
__name(getRegistrationScript, "getRegistrationScript");
|
|
123
|
+
|
|
124
|
+
// src/rn/use-dynamic-focus-registration.ts
|
|
125
|
+
function useDynamicFocusRegistration() {
|
|
126
|
+
useRegisterExtension({
|
|
127
|
+
extensionName: "dynamic-focus",
|
|
128
|
+
getRegistrationScript,
|
|
129
|
+
logger: Logger2
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
__name(useDynamicFocusRegistration, "useDynamicFocusRegistration");
|
|
133
|
+
|
|
134
|
+
// src/rn/use-dynamic-focus-events.ts
|
|
135
|
+
function useDynamicFocusEvent(event, callback) {
|
|
136
|
+
if (typeof event !== "string" || event.length === 0) {
|
|
137
|
+
throw new Error("Event parameter must be a non-empty string");
|
|
138
|
+
}
|
|
139
|
+
if (typeof callback !== "function") {
|
|
140
|
+
throw new Error("Callback parameter must be a function");
|
|
141
|
+
}
|
|
142
|
+
const context = useContext(MappedinContext);
|
|
143
|
+
const { extensions, mapData } = context;
|
|
144
|
+
if (!mapData) {
|
|
145
|
+
throw new Error("Map data is not available");
|
|
146
|
+
}
|
|
147
|
+
useDynamicFocusRegistration();
|
|
148
|
+
const extensionRegistrationState = extensions?.["dynamic-focus"]?.registrationState || "unregistered";
|
|
149
|
+
const extensionIsReady = extensionRegistrationState === "registered";
|
|
150
|
+
const processedCallback = useCallback(
|
|
151
|
+
(payload) => {
|
|
152
|
+
try {
|
|
153
|
+
let processedPayload = payload;
|
|
154
|
+
if (event === "focus" && payload.facades) {
|
|
155
|
+
processedPayload = {
|
|
156
|
+
...payload,
|
|
157
|
+
facades: hydrateFacades(mapData, payload.facades)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
callback(processedPayload);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
Logger2.error(`Error in dynamic focus event callback for ${String(event)}:`, error);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
[event, mapData, callback]
|
|
166
|
+
);
|
|
167
|
+
useEventCallback({
|
|
168
|
+
eventKey: `dynamic-focus:${String(event)}`,
|
|
169
|
+
callback: processedCallback,
|
|
170
|
+
setupScript: /* @__PURE__ */ __name(() => createEventSetupScript({
|
|
171
|
+
extensionName: "dynamic-focus",
|
|
172
|
+
eventName: String(event)
|
|
173
|
+
}), "setupScript"),
|
|
174
|
+
cleanupScript: /* @__PURE__ */ __name(() => createEventCleanupScript({
|
|
175
|
+
extensionName: "dynamic-focus",
|
|
176
|
+
eventName: String(event)
|
|
177
|
+
}), "cleanupScript"),
|
|
178
|
+
shouldInject: extensionIsReady
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
__name(useDynamicFocusEvent, "useDynamicFocusEvent");
|
|
182
|
+
|
|
183
|
+
// src/rn/use-dynamic-focus.ts
|
|
184
|
+
function useDynamicFocus() {
|
|
185
|
+
const context = useContext2(MappedinContext2);
|
|
186
|
+
const { bridge, extensions, updateExtensionState } = context;
|
|
187
|
+
useDynamicFocusRegistration();
|
|
188
|
+
const extensionState = extensions["dynamic-focus"];
|
|
189
|
+
const registrationState = extensionState?.registrationState || "unregistered";
|
|
190
|
+
const isReady = registrationState === "registered";
|
|
191
|
+
const isEnabled = extensionState?.isEnabled || false;
|
|
192
|
+
const [focusedFacades, setFocusedFacades] = useState(extensionState?.focusedFacades || []);
|
|
193
|
+
const extensionsRef = useRef(extensions);
|
|
194
|
+
extensionsRef.current = extensions;
|
|
195
|
+
useDynamicFocusEvent(
|
|
196
|
+
"focus",
|
|
197
|
+
useCallback2(
|
|
198
|
+
(event) => {
|
|
199
|
+
const newFocusedFacades = event.facades;
|
|
200
|
+
setFocusedFacades(newFocusedFacades);
|
|
201
|
+
updateExtensionState("dynamic-focus", (prev) => ({
|
|
202
|
+
...prev,
|
|
203
|
+
registrationState,
|
|
204
|
+
focusedFacades: newFocusedFacades
|
|
205
|
+
}));
|
|
206
|
+
},
|
|
207
|
+
[registrationState, updateExtensionState]
|
|
208
|
+
)
|
|
209
|
+
);
|
|
210
|
+
const callExtensionMethod = useCallback2(
|
|
211
|
+
async (method, args = []) => {
|
|
212
|
+
if (!bridge?.isReady) {
|
|
213
|
+
throw new Error("Bridge is not ready. Ensure the WebView is loaded.");
|
|
214
|
+
}
|
|
215
|
+
return await bridge.instruct({
|
|
216
|
+
type: "extension",
|
|
217
|
+
payload: {
|
|
218
|
+
name: "dynamic-focus",
|
|
219
|
+
method,
|
|
220
|
+
args
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
},
|
|
224
|
+
[bridge]
|
|
225
|
+
);
|
|
226
|
+
const enable = useCallback2(
|
|
227
|
+
async (options) => {
|
|
228
|
+
const currentExtensionState = extensionsRef.current?.["dynamic-focus"];
|
|
229
|
+
const currentIsEnabled = currentExtensionState?.isEnabled || false;
|
|
230
|
+
if (currentIsEnabled) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
await callExtensionMethod("enable", [options]);
|
|
234
|
+
updateExtensionState("dynamic-focus", (prev) => ({ ...prev, isEnabled: true }));
|
|
235
|
+
},
|
|
236
|
+
[callExtensionMethod, updateExtensionState]
|
|
237
|
+
);
|
|
238
|
+
const updateState = useCallback2(
|
|
239
|
+
async (state) => {
|
|
240
|
+
return await callExtensionMethod("updateState", [state]);
|
|
241
|
+
},
|
|
242
|
+
[callExtensionMethod]
|
|
243
|
+
);
|
|
244
|
+
const getState = useCallback2(async () => {
|
|
245
|
+
return await callExtensionMethod("getState");
|
|
246
|
+
}, [callExtensionMethod]);
|
|
247
|
+
const focus = useCallback2(
|
|
248
|
+
async (setFloor) => {
|
|
249
|
+
return await callExtensionMethod("focus", [setFloor]);
|
|
250
|
+
},
|
|
251
|
+
[callExtensionMethod]
|
|
252
|
+
);
|
|
253
|
+
const disable = useCallback2(async () => {
|
|
254
|
+
await callExtensionMethod("disable");
|
|
255
|
+
setFocusedFacades([]);
|
|
256
|
+
updateExtensionState("dynamic-focus", {
|
|
257
|
+
registrationState: "unregistered",
|
|
258
|
+
isEnabled: false,
|
|
259
|
+
focusedFacades: []
|
|
260
|
+
});
|
|
261
|
+
}, [callExtensionMethod, setFocusedFacades, updateExtensionState]);
|
|
262
|
+
return {
|
|
263
|
+
isReady,
|
|
264
|
+
isEnabled,
|
|
265
|
+
focusedFacades,
|
|
266
|
+
updateState,
|
|
267
|
+
getState,
|
|
268
|
+
focus,
|
|
269
|
+
disable,
|
|
270
|
+
enable
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
__name(useDynamicFocus, "useDynamicFocus");
|
|
274
|
+
export {
|
|
275
|
+
useDynamicFocus,
|
|
276
|
+
useDynamicFocusEvent
|
|
277
|
+
};
|
|
278
|
+
//# sourceMappingURL=index-rn.js.map
|