@cloudparse/up-miniapps-sdk 0.6.4 → 0.6.7

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/dist/index.cjs CHANGED
@@ -44,6 +44,7 @@ __export(src_exports, {
44
44
  MapMenuTitle: () => MapMenuTitle,
45
45
  MiniAppSDK: () => MiniAppSDK,
46
46
  MockLocationContext: () => MockLocationContext,
47
+ PullToRefresh: () => PullToRefresh,
47
48
  QRScanner: () => QRScanner,
48
49
  RouteLayer: () => RouteLayer,
49
50
  SDKMapProvider: () => SDKMapProvider,
@@ -266,11 +267,61 @@ var Bridge = class {
266
267
  }
267
268
  }
268
269
  /**
269
- * Internal handler for mock message processing, overrideable in test environments
270
+ * Internal handler for mock message processing, overrideable in test environments.
271
+ *
272
+ * Every mini-app that calls a bridge method also has to run standalone in a plain
273
+ * browser (dev, and this vault's own Chrome-based verification) with no native shell
274
+ * attached — `isNative()` is false, so `send()` never round-trips through the real
275
+ * host at all. Before this switch existed, EVERY unhandled type here resolved with
276
+ * plain `undefined` (see the `default` branch below), which silently broke any caller
277
+ * checking a result shape like `{success: boolean}` — `undefined?.success` reads as
278
+ * `false`, not "no answer", so e.g. `sdk.media.saveImage()` looked like a real
279
+ * permission-denied rejection in the browser instead of "there's no native shell
280
+ * here to ask." Add a `case` here — instead of leaving every mini-app to
281
+ * individually special-case "what happens when I call this with no shell attached" —
282
+ * whenever a bridge method's mock behavior should be more than a no-op.
270
283
  */
271
284
  handleMockMessage(type, payload) {
272
- console.warn(`[Bridge] Mock mode active: Unhandled message type ${type}`);
273
- return Promise.resolve();
285
+ switch (type) {
286
+ case "SAVE_IMAGE":
287
+ return this.mockSaveImage(
288
+ payload
289
+ );
290
+ default:
291
+ console.warn(
292
+ `[Bridge] Mock mode active: Unhandled message type ${type}`
293
+ );
294
+ return Promise.resolve();
295
+ }
296
+ }
297
+ /**
298
+ * Standalone-browser stand-in for the native `SAVE_IMAGE` handler: triggers a real
299
+ * browser download (an `<a download>` click) instead of writing to a device photo
300
+ * library, which doesn't exist here. Resolves `{success: true}` on a real trigger so
301
+ * every mini-app's own `result?.success` check gets the same shape/semantics as the
302
+ * real native response — no per-app "am I in mock mode" branching needed. Consumers
303
+ * can still keep their own `catch` fallback for the genuinely different case of a
304
+ * native shell that's missing its WebView bridge (see `sendOnce`'s own rejection
305
+ * path) — that's a real native edge case, not mocking, and this method never runs
306
+ * for it (`send()` only reaches `handleMockMessage` when `!isNative()`).
307
+ */
308
+ mockSaveImage(payload) {
309
+ if (typeof document === "undefined") {
310
+ return Promise.resolve({ success: false });
311
+ }
312
+ try {
313
+ const href = payload.base64.startsWith("data:") ? payload.base64 : `data:image/png;base64,${payload.base64}`;
314
+ const link = document.createElement("a");
315
+ link.href = href;
316
+ link.download = payload.filename ? `${payload.filename}.png` : "image.png";
317
+ document.body.appendChild(link);
318
+ link.click();
319
+ link.remove();
320
+ return Promise.resolve({ success: true });
321
+ } catch (err) {
322
+ console.warn("[Bridge] Mock SAVE_IMAGE download failed:", err);
323
+ return Promise.resolve({ success: false });
324
+ }
274
325
  }
275
326
  sendOnce(type, payload, timeoutMs) {
276
327
  return new Promise((resolve, reject) => {
@@ -3375,7 +3426,7 @@ async function generateQrCode(data, options = {}) {
3375
3426
  const size = options.size ?? DEFAULT_SIZE;
3376
3427
  const color = options.color ?? DEFAULT_COLOR;
3377
3428
  const backgroundColor = options.backgroundColor ?? DEFAULT_BACKGROUND;
3378
- const label = options.label || (options.appName ? `UP - ${options.appName}` : "");
3429
+ const label = options.label || (options.appName ? `${options.appName} by UP` : "");
3379
3430
  const qr = new import_qr_code_styling.default({
3380
3431
  backgroundOptions: {
3381
3432
  color: backgroundColor,
@@ -3714,7 +3765,7 @@ var RoutingService = {
3714
3765
  };
3715
3766
 
3716
3767
  // package.json
3717
- var version = "0.6.4";
3768
+ var version = "0.6.7";
3718
3769
 
3719
3770
  // src/sdk.ts
3720
3771
  function deepFreeze(obj) {
@@ -4860,18 +4911,271 @@ var DebugConsole = ({
4860
4911
  ] });
4861
4912
  };
4862
4913
 
4863
- // src/components/QRScanner.tsx
4864
- var import_jsqr2 = __toESM(require("jsqr"), 1);
4914
+ // src/components/PullToRefresh.tsx
4865
4915
  var import_react16 = require("react");
4866
4916
  var import_jsx_runtime18 = require("react/jsx-runtime");
4867
- function QRScanner({ onScan, onError, className = "" }) {
4868
- const videoRef = (0, import_react16.useRef)(null);
4869
- const canvasRef = (0, import_react16.useRef)(null);
4870
- const streamRef = (0, import_react16.useRef)(null);
4871
- const tickRequestRef = (0, import_react16.useRef)(null);
4872
- const hasScannedRef = (0, import_react16.useRef)(false);
4873
- const [isReady, setIsReady] = (0, import_react16.useState)(false);
4917
+ var DEFAULT_PULL_THRESHOLD = 64;
4918
+ var DEFAULT_MAX_PULL = 96;
4919
+ var RESISTANCE = 0.5;
4920
+ var DRAG_DEADZONE = 8;
4921
+ var FLING_FRICTION = 0.95;
4922
+ var FLING_MIN_VELOCITY = 0.02;
4923
+ function DefaultIndicator({
4924
+ progress,
4925
+ isRefreshing
4926
+ }) {
4927
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4928
+ "div",
4929
+ {
4930
+ style: {
4931
+ alignItems: "center",
4932
+ background: "rgba(24, 24, 27, 0.9)",
4933
+ border: "1px solid rgba(255, 255, 255, 0.1)",
4934
+ borderRadius: 9999,
4935
+ boxShadow: "0 4px 16px -4px rgba(0, 0, 0, 0.5)",
4936
+ display: "flex",
4937
+ height: 28,
4938
+ justifyContent: "center",
4939
+ width: 28
4940
+ },
4941
+ children: [
4942
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
4943
+ "svg",
4944
+ {
4945
+ height: 14,
4946
+ style: {
4947
+ animation: isRefreshing ? "up-sdk-ptr-spin 0.8s linear infinite" : void 0,
4948
+ color: isRefreshing ? "#a78bfa" : "#a1a1aa",
4949
+ transform: isRefreshing ? void 0 : `rotate(${progress * 360}deg)`
4950
+ },
4951
+ viewBox: "0 0 24 24",
4952
+ width: 14,
4953
+ children: [
4954
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("title", { children: "Refreshing" }),
4955
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4956
+ "path",
4957
+ {
4958
+ d: "M21 12a9 9 0 1 1-2.64-6.36",
4959
+ fill: "none",
4960
+ stroke: "currentColor",
4961
+ strokeLinecap: "round",
4962
+ strokeWidth: 2.5
4963
+ }
4964
+ )
4965
+ ]
4966
+ }
4967
+ ),
4968
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("style", { children: "@keyframes up-sdk-ptr-spin { to { transform: rotate(360deg); } }" })
4969
+ ]
4970
+ }
4971
+ );
4972
+ }
4973
+ var PullToRefresh = ({
4974
+ onRefresh,
4975
+ children,
4976
+ className = "",
4977
+ disabled = false,
4978
+ pullThreshold = DEFAULT_PULL_THRESHOLD,
4979
+ maxPull = DEFAULT_MAX_PULL,
4980
+ renderIndicator
4981
+ }) => {
4982
+ const containerRef = (0, import_react16.useRef)(null);
4983
+ const startYRef = (0, import_react16.useRef)(null);
4984
+ const lastYRef = (0, import_react16.useRef)(0);
4985
+ const lastMoveTimeRef = (0, import_react16.useRef)(0);
4986
+ const velocityRef = (0, import_react16.useRef)(0);
4987
+ const pointerIdRef = (0, import_react16.useRef)(null);
4988
+ const isPullingRef = (0, import_react16.useRef)(false);
4989
+ const pullDistanceRef = (0, import_react16.useRef)(0);
4990
+ const flingRafRef = (0, import_react16.useRef)(null);
4991
+ const [pullDistance, setPullDistance] = (0, import_react16.useState)(0);
4992
+ const [isRefreshing, setIsRefreshing] = (0, import_react16.useState)(false);
4993
+ const [isTracking, setIsTracking] = (0, import_react16.useState)(false);
4994
+ const disabledRef = (0, import_react16.useRef)(disabled);
4995
+ disabledRef.current = disabled;
4996
+ const onRefreshRef = (0, import_react16.useRef)(onRefresh);
4997
+ onRefreshRef.current = onRefresh;
4998
+ const pullThresholdRef = (0, import_react16.useRef)(pullThreshold);
4999
+ pullThresholdRef.current = pullThreshold;
5000
+ const maxPullRef = (0, import_react16.useRef)(maxPull);
5001
+ maxPullRef.current = maxPull;
4874
5002
  (0, import_react16.useEffect)(() => {
5003
+ const el = containerRef.current;
5004
+ if (!el) return;
5005
+ const updatePullDistance = (value) => {
5006
+ pullDistanceRef.current = value;
5007
+ setPullDistance(value);
5008
+ };
5009
+ const stopFling = () => {
5010
+ if (flingRafRef.current !== null) {
5011
+ cancelAnimationFrame(flingRafRef.current);
5012
+ flingRafRef.current = null;
5013
+ }
5014
+ };
5015
+ const resetTracking = () => {
5016
+ pointerIdRef.current = null;
5017
+ startYRef.current = null;
5018
+ isPullingRef.current = false;
5019
+ setIsTracking(false);
5020
+ updatePullDistance(0);
5021
+ };
5022
+ const runFling = () => {
5023
+ velocityRef.current *= FLING_FRICTION;
5024
+ if (Math.abs(velocityRef.current) < FLING_MIN_VELOCITY) {
5025
+ flingRafRef.current = null;
5026
+ return;
5027
+ }
5028
+ el.scrollTop -= velocityRef.current * 16;
5029
+ if (el.scrollTop <= 0 || el.scrollTop >= el.scrollHeight - el.clientHeight) {
5030
+ flingRafRef.current = null;
5031
+ return;
5032
+ }
5033
+ flingRafRef.current = requestAnimationFrame(runFling);
5034
+ };
5035
+ const handlePointerDown = (e) => {
5036
+ if (disabledRef.current) return;
5037
+ if (pointerIdRef.current !== null) return;
5038
+ stopFling();
5039
+ pointerIdRef.current = e.pointerId;
5040
+ startYRef.current = e.clientY;
5041
+ lastYRef.current = e.clientY;
5042
+ lastMoveTimeRef.current = performance.now();
5043
+ velocityRef.current = 0;
5044
+ isPullingRef.current = false;
5045
+ setIsTracking(true);
5046
+ try {
5047
+ el.setPointerCapture(e.pointerId);
5048
+ } catch {
5049
+ }
5050
+ };
5051
+ const handlePointerMove = (e) => {
5052
+ if (startYRef.current === null || e.pointerId !== pointerIdRef.current) {
5053
+ return;
5054
+ }
5055
+ const totalDelta = e.clientY - startYRef.current;
5056
+ if (!isPullingRef.current && Math.abs(totalDelta) < DRAG_DEADZONE) {
5057
+ return;
5058
+ }
5059
+ const now = performance.now();
5060
+ const stepDelta = e.clientY - lastYRef.current;
5061
+ const dt = Math.max(now - lastMoveTimeRef.current, 1);
5062
+ velocityRef.current = stepDelta / dt;
5063
+ lastYRef.current = e.clientY;
5064
+ lastMoveTimeRef.current = now;
5065
+ if (e.cancelable) e.preventDefault();
5066
+ const atTop = el.scrollTop <= 0;
5067
+ if (atTop && totalDelta > 0) {
5068
+ isPullingRef.current = true;
5069
+ updatePullDistance(
5070
+ Math.min(
5071
+ Math.max(totalDelta - DRAG_DEADZONE, 0) * RESISTANCE,
5072
+ maxPullRef.current
5073
+ )
5074
+ );
5075
+ return;
5076
+ }
5077
+ if (isPullingRef.current) {
5078
+ isPullingRef.current = false;
5079
+ updatePullDistance(0);
5080
+ }
5081
+ el.scrollTop -= stepDelta;
5082
+ };
5083
+ const handlePointerEnd = (e) => {
5084
+ if (startYRef.current === null || e.pointerId !== pointerIdRef.current) {
5085
+ return;
5086
+ }
5087
+ const wasPulling = isPullingRef.current;
5088
+ pointerIdRef.current = null;
5089
+ startYRef.current = null;
5090
+ isPullingRef.current = false;
5091
+ setIsTracking(false);
5092
+ if (!wasPulling) {
5093
+ if (Math.abs(velocityRef.current) > FLING_MIN_VELOCITY) {
5094
+ stopFling();
5095
+ flingRafRef.current = requestAnimationFrame(runFling);
5096
+ }
5097
+ return;
5098
+ }
5099
+ const shouldRefresh = pullDistanceRef.current >= pullThresholdRef.current;
5100
+ if (!shouldRefresh) {
5101
+ updatePullDistance(0);
5102
+ return;
5103
+ }
5104
+ setIsRefreshing(true);
5105
+ updatePullDistance(pullThresholdRef.current);
5106
+ Promise.resolve(onRefreshRef.current()).catch((err) => {
5107
+ console.error("Pull-to-refresh failed:", err);
5108
+ }).finally(() => {
5109
+ setIsRefreshing(false);
5110
+ updatePullDistance(0);
5111
+ });
5112
+ };
5113
+ const handlePointerCancel = (e) => {
5114
+ if (e.pointerId !== pointerIdRef.current) return;
5115
+ stopFling();
5116
+ resetTracking();
5117
+ };
5118
+ el.addEventListener("pointerdown", handlePointerDown);
5119
+ el.addEventListener("pointermove", handlePointerMove, { passive: false });
5120
+ el.addEventListener("pointerup", handlePointerEnd);
5121
+ el.addEventListener("pointercancel", handlePointerCancel);
5122
+ return () => {
5123
+ stopFling();
5124
+ el.removeEventListener("pointerdown", handlePointerDown);
5125
+ el.removeEventListener("pointermove", handlePointerMove);
5126
+ el.removeEventListener("pointerup", handlePointerEnd);
5127
+ el.removeEventListener("pointercancel", handlePointerCancel);
5128
+ };
5129
+ }, []);
5130
+ const indicatorHeight = isRefreshing ? pullThreshold : pullDistance;
5131
+ const progress = Math.min(indicatorHeight / pullThreshold, 1);
5132
+ const isSettling = pullDistance === 0 && !isRefreshing && !isTracking;
5133
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
5134
+ "div",
5135
+ {
5136
+ className: `up-sdk-pull-to-refresh ${className}`,
5137
+ ref: containerRef,
5138
+ style: {
5139
+ overflowY: "auto",
5140
+ overscrollBehavior: "none",
5141
+ touchAction: "none"
5142
+ },
5143
+ children: [
5144
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("style", { children: ".up-sdk-pull-to-refresh::-webkit-scrollbar { display: none; } .up-sdk-pull-to-refresh { scrollbar-width: none; -ms-overflow-style: none; }" }),
5145
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5146
+ "div",
5147
+ {
5148
+ style: {
5149
+ alignItems: "center",
5150
+ display: "flex",
5151
+ height: indicatorHeight,
5152
+ justifyContent: "center",
5153
+ overflow: "hidden",
5154
+ transition: isSettling ? "height 0.2s ease-out" : "none",
5155
+ userSelect: "none",
5156
+ width: "100%"
5157
+ },
5158
+ children: renderIndicator ? renderIndicator({ isRefreshing, progress }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DefaultIndicator, { isRefreshing, progress })
5159
+ }
5160
+ ),
5161
+ children
5162
+ ]
5163
+ }
5164
+ );
5165
+ };
5166
+
5167
+ // src/components/QRScanner.tsx
5168
+ var import_jsqr2 = __toESM(require("jsqr"), 1);
5169
+ var import_react17 = require("react");
5170
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5171
+ function QRScanner({ onScan, onError, className = "" }) {
5172
+ const videoRef = (0, import_react17.useRef)(null);
5173
+ const canvasRef = (0, import_react17.useRef)(null);
5174
+ const streamRef = (0, import_react17.useRef)(null);
5175
+ const tickRequestRef = (0, import_react17.useRef)(null);
5176
+ const hasScannedRef = (0, import_react17.useRef)(false);
5177
+ const [isReady, setIsReady] = (0, import_react17.useState)(false);
5178
+ (0, import_react17.useEffect)(() => {
4875
5179
  let cancelled = false;
4876
5180
  hasScannedRef.current = false;
4877
5181
  const cleanup = () => {
@@ -4954,7 +5258,7 @@ function QRScanner({ onScan, onError, className = "" }) {
4954
5258
  cleanup();
4955
5259
  };
4956
5260
  }, []);
4957
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
5261
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
4958
5262
  "div",
4959
5263
  {
4960
5264
  className,
@@ -4966,7 +5270,7 @@ function QRScanner({ onScan, onError, className = "" }) {
4966
5270
  position: "relative"
4967
5271
  },
4968
5272
  children: [
4969
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5273
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4970
5274
  "video",
4971
5275
  {
4972
5276
  playsInline: true,
@@ -4974,8 +5278,8 @@ function QRScanner({ onScan, onError, className = "" }) {
4974
5278
  style: { height: "100%", objectFit: "cover", width: "100%" }
4975
5279
  }
4976
5280
  ),
4977
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
4978
- isReady && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5281
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("canvas", { ref: canvasRef, style: { display: "none" } }),
5282
+ isReady && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4979
5283
  "div",
4980
5284
  {
4981
5285
  style: {
@@ -4996,30 +5300,30 @@ function QRScanner({ onScan, onError, className = "" }) {
4996
5300
  }
4997
5301
 
4998
5302
  // src/components/SDKProvider.tsx
4999
- var import_react17 = require("react");
5000
- var import_jsx_runtime19 = require("react/jsx-runtime");
5001
- var SDKContext = (0, import_react17.createContext)({ isMocked: false });
5002
- var useIsMocked = () => (0, import_react17.useContext)(SDKContext).isMocked;
5303
+ var import_react18 = require("react");
5304
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5305
+ var SDKContext = (0, import_react18.createContext)({ isMocked: false });
5306
+ var useIsMocked = () => (0, import_react18.useContext)(SDKContext).isMocked;
5003
5307
  var SDKProvider = ({
5004
5308
  children,
5005
5309
  debug = false,
5006
5310
  ...mockerProps
5007
5311
  }) => {
5008
5312
  const isMocked = typeof window !== "undefined" && !(window.__UP_REACT_NATIVE_APP__ === true || !!window.ReactNativeWebView);
5009
- const value = (0, import_react17.useMemo)(() => ({ isMocked }), [isMocked]);
5010
- const content = /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
5313
+ const value = (0, import_react18.useMemo)(() => ({ isMocked }), [isMocked]);
5314
+ const content = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
5011
5315
  children,
5012
- (debug || isMocked) && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DebugConsole, {})
5316
+ (debug || isMocked) && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DebugConsole, {})
5013
5317
  ] });
5014
5318
  if (isMocked) {
5015
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
5319
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SDKContext.Provider, { value, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(BridgeMocker, { ...mockerProps, children: content }) });
5016
5320
  }
5017
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SDKContext.Provider, { value, children: content });
5321
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SDKContext.Provider, { value, children: content });
5018
5322
  };
5019
5323
 
5020
5324
  // src/components/SwipeCarousel.tsx
5021
- var import_react18 = require("react");
5022
- var import_jsx_runtime20 = require("react/jsx-runtime");
5325
+ var import_react19 = require("react");
5326
+ var import_jsx_runtime21 = require("react/jsx-runtime");
5023
5327
  var DIRECTION_LOCK_THRESHOLD_PX = 8;
5024
5328
  var SWIPE_DISTANCE_THRESHOLD_PX = 40;
5025
5329
  var SWIPE_VELOCITY_THRESHOLD = 0.4;
@@ -5046,28 +5350,28 @@ var SwipeCarousel = ({
5046
5350
  overscan = DEFAULT_OVERSCAN,
5047
5351
  visibleOverscan = DEFAULT_VISIBLE_OVERSCAN
5048
5352
  }) => {
5049
- const containerRef = (0, import_react18.useRef)(null);
5050
- const [containerWidth, setContainerWidth] = (0, import_react18.useState)(0);
5051
- const [dragX, setDragX] = (0, import_react18.useState)(0);
5052
- const [dragY, setDragY] = (0, import_react18.useState)(0);
5053
- const [isDraggingX, setIsDraggingX] = (0, import_react18.useState)(false);
5054
- const [isDraggingY, setIsDraggingY] = (0, import_react18.useState)(false);
5055
- const touchStateRef = (0, import_react18.useRef)(null);
5056
- const [internalIndex, setInternalIndex] = (0, import_react18.useState)(
5353
+ const containerRef = (0, import_react19.useRef)(null);
5354
+ const [containerWidth, setContainerWidth] = (0, import_react19.useState)(0);
5355
+ const [dragX, setDragX] = (0, import_react19.useState)(0);
5356
+ const [dragY, setDragY] = (0, import_react19.useState)(0);
5357
+ const [isDraggingX, setIsDraggingX] = (0, import_react19.useState)(false);
5358
+ const [isDraggingY, setIsDraggingY] = (0, import_react19.useState)(false);
5359
+ const touchStateRef = (0, import_react19.useRef)(null);
5360
+ const [internalIndex, setInternalIndex] = (0, import_react19.useState)(
5057
5361
  () => Math.max(
5058
5362
  0,
5059
5363
  items.findIndex((item) => item.id === activeId)
5060
5364
  )
5061
5365
  );
5062
- const prevActiveIdRef = (0, import_react18.useRef)(activeId);
5063
- const [timingWaiting, setTimingWaiting] = (0, import_react18.useState)(true);
5064
- (0, import_react18.useEffect)(() => {
5366
+ const prevActiveIdRef = (0, import_react19.useRef)(activeId);
5367
+ const [timingWaiting, setTimingWaiting] = (0, import_react19.useState)(true);
5368
+ (0, import_react19.useEffect)(() => {
5065
5369
  const timer = setTimeout(() => {
5066
5370
  setTimingWaiting(false);
5067
5371
  }, 1e3);
5068
5372
  return () => clearTimeout(timer);
5069
5373
  }, []);
5070
- (0, import_react18.useEffect)(() => {
5374
+ (0, import_react19.useEffect)(() => {
5071
5375
  if (activeId !== prevActiveIdRef.current) {
5072
5376
  const idx = items.findIndex((item) => item.id === activeId);
5073
5377
  if (idx !== -1) setInternalIndex(idx);
@@ -5078,7 +5382,7 @@ var SwipeCarousel = ({
5078
5382
  Math.max(internalIndex, 0),
5079
5383
  Math.max(items.length - 1, 0)
5080
5384
  );
5081
- (0, import_react18.useLayoutEffect)(() => {
5385
+ (0, import_react19.useLayoutEffect)(() => {
5082
5386
  const el = containerRef.current;
5083
5387
  if (!el) return;
5084
5388
  const update = () => setContainerWidth(el.clientWidth);
@@ -5196,7 +5500,7 @@ var SwipeCarousel = ({
5196
5500
  };
5197
5501
  const windowStart = Math.max(0, activeIndex - overscan);
5198
5502
  const windowEnd = Math.min(items.length - 1, activeIndex + overscan);
5199
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5503
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5200
5504
  "div",
5201
5505
  {
5202
5506
  className: `relative overflow-hidden touch-pan-y ${className ?? ""}`,
@@ -5205,7 +5509,7 @@ var SwipeCarousel = ({
5205
5509
  onTouchMove: handleTouchMove,
5206
5510
  onTouchStart: handleTouchStart,
5207
5511
  ref: containerRef,
5208
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5512
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5209
5513
  "div",
5210
5514
  {
5211
5515
  className: "relative h-full",
@@ -5220,7 +5524,7 @@ var SwipeCarousel = ({
5220
5524
  const verticalOffset = isActive ? dragY : 0;
5221
5525
  const distance = Math.abs(index - activeIndex);
5222
5526
  const isVisible = distance <= visibleOverscan;
5223
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5527
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5224
5528
  "div",
5225
5529
  {
5226
5530
  className: `absolute top-0 left-0 h-full shrink-0 ${itemClassName ?? ""} ${item.className ?? ""}`,
@@ -5561,6 +5865,7 @@ var src_default = sdk;
5561
5865
  MapMenuTitle,
5562
5866
  MiniAppSDK,
5563
5867
  MockLocationContext,
5868
+ PullToRefresh,
5564
5869
  QRScanner,
5565
5870
  RouteLayer,
5566
5871
  SDKMapProvider,