@thelacanians/vue-native-runtime 0.4.14 → 0.6.0
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 +2072 -345
- package/dist/index.d.cts +1024 -215
- package/dist/index.d.ts +1024 -215
- package/dist/index.js +2079 -349
- package/dist/testing.cjs +64 -0
- package/dist/testing.d.cts +42 -0
- package/dist/testing.d.ts +42 -0
- package/dist/testing.js +38 -0
- package/package.json +23 -7
package/dist/index.js
CHANGED
|
@@ -8,16 +8,25 @@ import { createRenderer } from "@vue/runtime-core";
|
|
|
8
8
|
import { markRaw } from "@vue/reactivity";
|
|
9
9
|
var nextNodeId = 1;
|
|
10
10
|
var MAX_NODE_ID = 2147483647;
|
|
11
|
+
var activeNodeIds = /* @__PURE__ */ new Set();
|
|
11
12
|
function resetNodeId() {
|
|
12
13
|
nextNodeId = 1;
|
|
14
|
+
activeNodeIds.clear();
|
|
15
|
+
}
|
|
16
|
+
function releaseNodeId(id) {
|
|
17
|
+
activeNodeIds.delete(id);
|
|
13
18
|
}
|
|
14
19
|
function getNextNodeId() {
|
|
15
20
|
const id = nextNodeId;
|
|
16
21
|
if (nextNodeId >= MAX_NODE_ID) {
|
|
17
22
|
nextNodeId = 1;
|
|
23
|
+
while (activeNodeIds.has(nextNodeId) && nextNodeId < MAX_NODE_ID) {
|
|
24
|
+
nextNodeId++;
|
|
25
|
+
}
|
|
18
26
|
} else {
|
|
19
27
|
nextNodeId++;
|
|
20
28
|
}
|
|
29
|
+
activeNodeIds.add(id);
|
|
21
30
|
return id;
|
|
22
31
|
}
|
|
23
32
|
function createNativeNode(type) {
|
|
@@ -56,6 +65,7 @@ function createCommentNode(_text) {
|
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
// src/bridge.ts
|
|
68
|
+
var bridgeGlobals = globalThis;
|
|
59
69
|
var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
60
70
|
constructor() {
|
|
61
71
|
/** Pending operations waiting to be flushed to native */
|
|
@@ -97,7 +107,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
97
107
|
const ops = this.pendingOps;
|
|
98
108
|
this.pendingOps = [];
|
|
99
109
|
const json = JSON.stringify(ops);
|
|
100
|
-
const flushFn =
|
|
110
|
+
const flushFn = bridgeGlobals.__VN_flushOperations;
|
|
101
111
|
if (typeof flushFn === "function") {
|
|
102
112
|
try {
|
|
103
113
|
flushFn(json);
|
|
@@ -177,6 +187,16 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
177
187
|
updateStyle(nodeId, key, value) {
|
|
178
188
|
this.enqueue("updateStyle", [nodeId, { [key]: value }]);
|
|
179
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Update multiple style properties on a native view in a single bridge op.
|
|
192
|
+
* Swift/Kotlin handler: handleUpdateStyle(args: [nodeId, { key1: val1, key2: val2, ... }])
|
|
193
|
+
*
|
|
194
|
+
* More efficient than calling updateStyle() per property — sends one op
|
|
195
|
+
* instead of N ops, reducing JSON overhead and bridge dispatch.
|
|
196
|
+
*/
|
|
197
|
+
updateStyles(nodeId, styles) {
|
|
198
|
+
this.enqueue("updateStyle", [nodeId, styles]);
|
|
199
|
+
}
|
|
180
200
|
// ---------------------------------------------------------------------------
|
|
181
201
|
// Tree mutations
|
|
182
202
|
// ---------------------------------------------------------------------------
|
|
@@ -264,6 +284,8 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
264
284
|
* a crash or unregistered module), the Promise rejects with a clear error instead
|
|
265
285
|
* of hanging forever.
|
|
266
286
|
*/
|
|
287
|
+
// Native module results are intentionally dynamic; callers often narrow them
|
|
288
|
+
// ad hoc based on the module contract rather than a shared generated type.
|
|
267
289
|
invokeNativeModule(moduleName, methodName, args = [], timeoutMs = 3e4) {
|
|
268
290
|
return new Promise((resolve, reject) => {
|
|
269
291
|
const callbackId = this.nextCallbackId;
|
|
@@ -291,7 +313,11 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
291
313
|
}
|
|
292
314
|
}
|
|
293
315
|
}
|
|
294
|
-
this.pendingCallbacks.set(callbackId, {
|
|
316
|
+
this.pendingCallbacks.set(callbackId, {
|
|
317
|
+
resolve: (result) => resolve(result),
|
|
318
|
+
reject: (error) => reject(error),
|
|
319
|
+
timeoutId
|
|
320
|
+
});
|
|
295
321
|
this.enqueue("invokeNativeModule", [moduleName, methodName, args, callbackId]);
|
|
296
322
|
});
|
|
297
323
|
}
|
|
@@ -323,6 +349,28 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
323
349
|
pending.resolve(result);
|
|
324
350
|
}
|
|
325
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Create teleport markers in native.
|
|
354
|
+
* Used for Teleport component to render content outside parent hierarchy.
|
|
355
|
+
*/
|
|
356
|
+
createTeleport(parentId, startId, endId) {
|
|
357
|
+
this.enqueue("createTeleport", [parentId, startId, endId]);
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Remove teleport markers from native.
|
|
361
|
+
* Cleans up teleport containers and markers.
|
|
362
|
+
*/
|
|
363
|
+
removeTeleport(parentId, startId, endId) {
|
|
364
|
+
this.enqueue("removeTeleport", [parentId, startId, endId]);
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Move a node to a teleport target.
|
|
368
|
+
* @param target - Teleport target name ('modal', 'root', etc.)
|
|
369
|
+
* @param nodeId - Node ID to teleport
|
|
370
|
+
*/
|
|
371
|
+
teleportTo(target, nodeId) {
|
|
372
|
+
this.enqueue("teleportTo", [target, nodeId]);
|
|
373
|
+
}
|
|
326
374
|
// ---------------------------------------------------------------------------
|
|
327
375
|
// Global push events
|
|
328
376
|
// ---------------------------------------------------------------------------
|
|
@@ -343,7 +391,7 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
343
391
|
* Called from Swift via globalThis.__VN_handleGlobalEvent when a push event fires.
|
|
344
392
|
*/
|
|
345
393
|
handleGlobalEvent(eventName, payloadJSON) {
|
|
346
|
-
let payload;
|
|
394
|
+
let payload = {};
|
|
347
395
|
try {
|
|
348
396
|
payload = JSON.parse(payloadJSON);
|
|
349
397
|
} catch {
|
|
@@ -351,9 +399,9 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
351
399
|
}
|
|
352
400
|
const handlers = this.globalEventHandlers.get(eventName);
|
|
353
401
|
if (handlers) {
|
|
354
|
-
handlers.forEach((
|
|
402
|
+
handlers.forEach((h33) => {
|
|
355
403
|
try {
|
|
356
|
-
|
|
404
|
+
h33(payload);
|
|
357
405
|
} catch (err) {
|
|
358
406
|
console.error(`[VueNative] Error in global event handler "${eventName}":`, err);
|
|
359
407
|
}
|
|
@@ -370,6 +418,9 @@ var _NativeBridgeImpl = class _NativeBridgeImpl {
|
|
|
370
418
|
this.pendingOps = [];
|
|
371
419
|
this.flushScheduled = false;
|
|
372
420
|
this.eventHandlers.clear();
|
|
421
|
+
for (const pending of this.pendingCallbacks.values()) {
|
|
422
|
+
clearTimeout(pending.timeoutId);
|
|
423
|
+
}
|
|
373
424
|
this.pendingCallbacks.clear();
|
|
374
425
|
this.nextCallbackId = 1;
|
|
375
426
|
this.globalEventHandlers.clear();
|
|
@@ -380,15 +431,14 @@ _NativeBridgeImpl.MAX_CALLBACK_ID = 2147483647;
|
|
|
380
431
|
/** Maximum number of pending callbacks before evicting the oldest */
|
|
381
432
|
_NativeBridgeImpl.MAX_PENDING_CALLBACKS = 1e3;
|
|
382
433
|
var NativeBridgeImpl = _NativeBridgeImpl;
|
|
383
|
-
if (typeof
|
|
384
|
-
;
|
|
385
|
-
globalThis.__DEV__ = true;
|
|
434
|
+
if (typeof bridgeGlobals.__DEV__ === "undefined") {
|
|
435
|
+
bridgeGlobals.__DEV__ = true;
|
|
386
436
|
}
|
|
387
437
|
var NativeBridge = new NativeBridgeImpl();
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
438
|
+
bridgeGlobals.__VN_handleEvent = NativeBridge.handleNativeEvent.bind(NativeBridge);
|
|
439
|
+
bridgeGlobals.__VN_resolveCallback = NativeBridge.resolveCallback.bind(NativeBridge);
|
|
440
|
+
bridgeGlobals.__VN_handleGlobalEvent = NativeBridge.handleGlobalEvent.bind(NativeBridge);
|
|
441
|
+
bridgeGlobals.__VN_teardown = () => {
|
|
392
442
|
NativeBridge.reset();
|
|
393
443
|
resetNodeId();
|
|
394
444
|
};
|
|
@@ -397,20 +447,30 @@ globalThis.__VN_teardown = () => {
|
|
|
397
447
|
function toEventName(key) {
|
|
398
448
|
return key.slice(2).toLowerCase();
|
|
399
449
|
}
|
|
450
|
+
function isEventHandler(value) {
|
|
451
|
+
return typeof value === "function";
|
|
452
|
+
}
|
|
400
453
|
function patchStyle(nodeId, prevStyle, nextStyle) {
|
|
401
454
|
try {
|
|
402
|
-
const prev = prevStyle
|
|
403
|
-
const next = nextStyle
|
|
455
|
+
const prev = typeof prevStyle === "object" && prevStyle !== null ? prevStyle : {};
|
|
456
|
+
const next = typeof nextStyle === "object" && nextStyle !== null ? nextStyle : {};
|
|
457
|
+
const changes = {};
|
|
458
|
+
let hasChanges = false;
|
|
404
459
|
for (const key in next) {
|
|
405
460
|
if (next[key] !== prev[key]) {
|
|
406
|
-
|
|
461
|
+
changes[key] = next[key];
|
|
462
|
+
hasChanges = true;
|
|
407
463
|
}
|
|
408
464
|
}
|
|
409
465
|
for (const key in prev) {
|
|
410
466
|
if (!(key in next)) {
|
|
411
|
-
|
|
467
|
+
changes[key] = null;
|
|
468
|
+
hasChanges = true;
|
|
412
469
|
}
|
|
413
470
|
}
|
|
471
|
+
if (hasChanges) {
|
|
472
|
+
NativeBridge.updateStyles(nodeId, changes);
|
|
473
|
+
}
|
|
414
474
|
} catch (err) {
|
|
415
475
|
console.error(`[VueNative] Error patching style on node ${nodeId}:`, err);
|
|
416
476
|
}
|
|
@@ -471,7 +531,7 @@ var nodeOps = {
|
|
|
471
531
|
if (prevValue) {
|
|
472
532
|
NativeBridge.removeEventListener(el.id, eventName);
|
|
473
533
|
}
|
|
474
|
-
if (nextValue) {
|
|
534
|
+
if (isEventHandler(nextValue)) {
|
|
475
535
|
NativeBridge.addEventListener(el.id, eventName, nextValue);
|
|
476
536
|
}
|
|
477
537
|
return;
|
|
@@ -547,6 +607,7 @@ var nodeOps = {
|
|
|
547
607
|
} catch (err) {
|
|
548
608
|
console.error(`[VueNative] Error removing node ${child.id}:`, err);
|
|
549
609
|
}
|
|
610
|
+
releaseNodeId(child.id);
|
|
550
611
|
}
|
|
551
612
|
},
|
|
552
613
|
/**
|
|
@@ -564,6 +625,25 @@ var nodeOps = {
|
|
|
564
625
|
const idx = parent.children.indexOf(node);
|
|
565
626
|
if (idx === -1 || idx >= parent.children.length - 1) return null;
|
|
566
627
|
return parent.children[idx + 1];
|
|
628
|
+
},
|
|
629
|
+
/**
|
|
630
|
+
* Insert static content (for Teleport).
|
|
631
|
+
* Creates teleport boundary markers.
|
|
632
|
+
*/
|
|
633
|
+
insertStaticContent(content, parent, anchor, _namespace, _start, _end) {
|
|
634
|
+
const startNode = createNativeNode("__TELEPORT_START__");
|
|
635
|
+
const endNode = createNativeNode("__TELEPORT_END__");
|
|
636
|
+
if (anchor) {
|
|
637
|
+
const idx = parent.children.indexOf(anchor);
|
|
638
|
+
if (idx !== -1) {
|
|
639
|
+
parent.children.splice(idx, 0, startNode);
|
|
640
|
+
parent.children.splice(idx + 1, 0, endNode);
|
|
641
|
+
}
|
|
642
|
+
} else {
|
|
643
|
+
parent.children.push(startNode, endNode);
|
|
644
|
+
}
|
|
645
|
+
NativeBridge.createTeleport(parent.id, startNode.id, endNode.id);
|
|
646
|
+
return [startNode, endNode];
|
|
567
647
|
}
|
|
568
648
|
};
|
|
569
649
|
function findNextNonComment(parent, anchor) {
|
|
@@ -652,6 +732,16 @@ var VButton = defineComponent3({
|
|
|
652
732
|
|
|
653
733
|
// src/components/VInput.ts
|
|
654
734
|
import { defineComponent as defineComponent4, h as h4, ref } from "@vue/runtime-core";
|
|
735
|
+
function extractText(payload) {
|
|
736
|
+
if (typeof payload === "string") {
|
|
737
|
+
return payload;
|
|
738
|
+
}
|
|
739
|
+
if (typeof payload === "object" && payload !== null && "text" in payload) {
|
|
740
|
+
const text = payload.text;
|
|
741
|
+
return typeof text === "string" ? text : "";
|
|
742
|
+
}
|
|
743
|
+
return "";
|
|
744
|
+
}
|
|
655
745
|
var VInput = defineComponent4({
|
|
656
746
|
name: "VInput",
|
|
657
747
|
props: {
|
|
@@ -699,13 +789,11 @@ var VInput = defineComponent4({
|
|
|
699
789
|
};
|
|
700
790
|
const onCompositionend = (payload) => {
|
|
701
791
|
isComposing.value = false;
|
|
702
|
-
|
|
703
|
-
emit("update:modelValue", text);
|
|
792
|
+
emit("update:modelValue", extractText(payload));
|
|
704
793
|
};
|
|
705
794
|
const onChangetext = (payload) => {
|
|
706
795
|
if (isComposing.value) return;
|
|
707
|
-
|
|
708
|
-
emit("update:modelValue", text);
|
|
796
|
+
emit("update:modelValue", extractText(payload));
|
|
709
797
|
};
|
|
710
798
|
const onFocus = (payload) => {
|
|
711
799
|
emit("focus", payload);
|
|
@@ -765,7 +853,8 @@ var VSwitch = defineComponent5({
|
|
|
765
853
|
emits: ["update:modelValue", "change"],
|
|
766
854
|
setup(props, { emit }) {
|
|
767
855
|
const onChange = (payload) => {
|
|
768
|
-
const
|
|
856
|
+
const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
|
|
857
|
+
const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
|
|
769
858
|
emit("update:modelValue", value);
|
|
770
859
|
emit("change", value);
|
|
771
860
|
};
|
|
@@ -929,9 +1018,9 @@ var VImage = defineComponent8({
|
|
|
929
1018
|
loading.value = false;
|
|
930
1019
|
emit("load");
|
|
931
1020
|
};
|
|
932
|
-
const onError = (
|
|
1021
|
+
const onError = (event) => {
|
|
933
1022
|
loading.value = false;
|
|
934
|
-
emit("error",
|
|
1023
|
+
emit("error", event);
|
|
935
1024
|
};
|
|
936
1025
|
expose({ loading });
|
|
937
1026
|
return () => h8(
|
|
@@ -1005,6 +1094,20 @@ var VSlider = defineComponent11({
|
|
|
1005
1094
|
|
|
1006
1095
|
// src/components/VList.ts
|
|
1007
1096
|
import { defineComponent as defineComponent12, h as h12 } from "@vue/runtime-core";
|
|
1097
|
+
|
|
1098
|
+
// src/composables/usePlatform.ts
|
|
1099
|
+
function usePlatform() {
|
|
1100
|
+
const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
|
|
1101
|
+
const isIOS = platform === "ios";
|
|
1102
|
+
const isAndroid = platform === "android";
|
|
1103
|
+
const isMacOS = platform === "macos";
|
|
1104
|
+
const isApple = isIOS || isMacOS;
|
|
1105
|
+
const isDesktop = isMacOS;
|
|
1106
|
+
const isMobile = isIOS || isAndroid;
|
|
1107
|
+
return { platform, isIOS, isAndroid, isMacOS, isApple, isDesktop, isMobile };
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// src/components/VList.ts
|
|
1008
1111
|
var VList = defineComponent12({
|
|
1009
1112
|
name: "VList",
|
|
1010
1113
|
props: {
|
|
@@ -1045,13 +1148,27 @@ var VList = defineComponent12({
|
|
|
1045
1148
|
},
|
|
1046
1149
|
emits: ["scroll", "endReached"],
|
|
1047
1150
|
setup(props, { slots, emit }) {
|
|
1151
|
+
const { isAndroid } = usePlatform();
|
|
1048
1152
|
let lastScrollEmit = 0;
|
|
1153
|
+
let endReachedFired = false;
|
|
1049
1154
|
const onScroll = (e) => {
|
|
1050
1155
|
const now = Date.now();
|
|
1051
1156
|
if (now - lastScrollEmit >= 16) {
|
|
1052
1157
|
lastScrollEmit = now;
|
|
1053
1158
|
emit("scroll", e);
|
|
1054
1159
|
}
|
|
1160
|
+
if (props.horizontal && !isAndroid) {
|
|
1161
|
+
const contentWidth = e.contentWidth ?? 0;
|
|
1162
|
+
const layoutWidth = e.layoutWidth ?? 0;
|
|
1163
|
+
const distanceFromEnd = contentWidth - layoutWidth - (e.x ?? 0);
|
|
1164
|
+
const threshold = layoutWidth * 0.2;
|
|
1165
|
+
if (contentWidth > layoutWidth && distanceFromEnd < threshold && !endReachedFired) {
|
|
1166
|
+
endReachedFired = true;
|
|
1167
|
+
emit("endReached");
|
|
1168
|
+
} else if (distanceFromEnd >= threshold) {
|
|
1169
|
+
endReachedFired = false;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1055
1172
|
};
|
|
1056
1173
|
return () => {
|
|
1057
1174
|
const items = props.data ?? [];
|
|
@@ -1097,6 +1214,31 @@ var VList = defineComponent12({
|
|
|
1097
1214
|
h12("VView", { key: "__footer__", style: { flexShrink: 0 } }, slots.footer())
|
|
1098
1215
|
);
|
|
1099
1216
|
}
|
|
1217
|
+
if (props.horizontal && !isAndroid) {
|
|
1218
|
+
return h12(
|
|
1219
|
+
"VScrollView",
|
|
1220
|
+
{
|
|
1221
|
+
style: props.style,
|
|
1222
|
+
horizontal: true,
|
|
1223
|
+
showsVerticalScrollIndicator: false,
|
|
1224
|
+
showsHorizontalScrollIndicator: props.showsScrollIndicator,
|
|
1225
|
+
bounces: props.bounces,
|
|
1226
|
+
onScroll
|
|
1227
|
+
},
|
|
1228
|
+
[
|
|
1229
|
+
h12(
|
|
1230
|
+
"VView",
|
|
1231
|
+
{
|
|
1232
|
+
style: {
|
|
1233
|
+
flexDirection: "row",
|
|
1234
|
+
alignItems: "stretch"
|
|
1235
|
+
}
|
|
1236
|
+
},
|
|
1237
|
+
children
|
|
1238
|
+
)
|
|
1239
|
+
]
|
|
1240
|
+
);
|
|
1241
|
+
}
|
|
1100
1242
|
return h12(
|
|
1101
1243
|
"VList",
|
|
1102
1244
|
{
|
|
@@ -1200,9 +1342,9 @@ var VAlertDialog = defineComponent14({
|
|
|
1200
1342
|
title: props.title,
|
|
1201
1343
|
message: props.message,
|
|
1202
1344
|
buttons: resolvedButtons,
|
|
1203
|
-
onConfirm: (
|
|
1345
|
+
onConfirm: (event) => emit("confirm", event),
|
|
1204
1346
|
onCancel: () => emit("cancel"),
|
|
1205
|
-
onAction: (
|
|
1347
|
+
onAction: (event) => emit("action", event)
|
|
1206
1348
|
});
|
|
1207
1349
|
};
|
|
1208
1350
|
}
|
|
@@ -1251,9 +1393,9 @@ var VWebView = defineComponent16({
|
|
|
1251
1393
|
source: sanitizedSource.value,
|
|
1252
1394
|
style: props.style,
|
|
1253
1395
|
javaScriptEnabled: props.javaScriptEnabled,
|
|
1254
|
-
onLoad: (
|
|
1255
|
-
onError: (
|
|
1256
|
-
onMessage: (
|
|
1396
|
+
onLoad: (event) => emit("load", event),
|
|
1397
|
+
onError: (event) => emit("error", event),
|
|
1398
|
+
onMessage: (event) => emit("message", event)
|
|
1257
1399
|
});
|
|
1258
1400
|
}
|
|
1259
1401
|
});
|
|
@@ -1562,7 +1704,8 @@ var VCheckbox = defineComponent24({
|
|
|
1562
1704
|
emits: ["update:modelValue", "change"],
|
|
1563
1705
|
setup(props, { emit }) {
|
|
1564
1706
|
const onChange = (payload) => {
|
|
1565
|
-
const
|
|
1707
|
+
const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
|
|
1708
|
+
const value = typeof nextValue === "boolean" ? nextValue : Boolean(nextValue);
|
|
1566
1709
|
emit("update:modelValue", value);
|
|
1567
1710
|
emit("change", value);
|
|
1568
1711
|
};
|
|
@@ -1582,6 +1725,10 @@ var VCheckbox = defineComponent24({
|
|
|
1582
1725
|
|
|
1583
1726
|
// src/components/VRadio.ts
|
|
1584
1727
|
import { defineComponent as defineComponent25, h as h25 } from "@vue/runtime-core";
|
|
1728
|
+
function extractRadioValue(payload) {
|
|
1729
|
+
const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
|
|
1730
|
+
return typeof nextValue === "string" ? nextValue : void 0;
|
|
1731
|
+
}
|
|
1585
1732
|
var VRadio = defineComponent25({
|
|
1586
1733
|
name: "VRadio",
|
|
1587
1734
|
props: {
|
|
@@ -1604,7 +1751,7 @@ var VRadio = defineComponent25({
|
|
|
1604
1751
|
emits: ["update:modelValue", "change"],
|
|
1605
1752
|
setup(props, { emit }) {
|
|
1606
1753
|
const onChange = (payload) => {
|
|
1607
|
-
const value = payload
|
|
1754
|
+
const value = extractRadioValue(payload);
|
|
1608
1755
|
emit("update:modelValue", value);
|
|
1609
1756
|
emit("change", value);
|
|
1610
1757
|
};
|
|
@@ -1622,6 +1769,10 @@ var VRadio = defineComponent25({
|
|
|
1622
1769
|
|
|
1623
1770
|
// src/components/VDropdown.ts
|
|
1624
1771
|
import { defineComponent as defineComponent26, h as h26 } from "@vue/runtime-core";
|
|
1772
|
+
function extractDropdownValue(payload) {
|
|
1773
|
+
const nextValue = typeof payload === "object" && payload !== null && "value" in payload ? payload.value : payload;
|
|
1774
|
+
return typeof nextValue === "string" ? nextValue : void 0;
|
|
1775
|
+
}
|
|
1625
1776
|
var VDropdown = defineComponent26({
|
|
1626
1777
|
name: "VDropdown",
|
|
1627
1778
|
props: {
|
|
@@ -1648,7 +1799,7 @@ var VDropdown = defineComponent26({
|
|
|
1648
1799
|
emits: ["update:modelValue", "change"],
|
|
1649
1800
|
setup(props, { emit }) {
|
|
1650
1801
|
const onChange = (payload) => {
|
|
1651
|
-
const value = payload
|
|
1802
|
+
const value = extractDropdownValue(payload);
|
|
1652
1803
|
emit("update:modelValue", value);
|
|
1653
1804
|
emit("change", value);
|
|
1654
1805
|
};
|
|
@@ -1690,85 +1841,1042 @@ var VVideo = defineComponent27({
|
|
|
1690
1841
|
setup(props, { emit }) {
|
|
1691
1842
|
return () => h27("VVideo", {
|
|
1692
1843
|
...props,
|
|
1693
|
-
onReady: (
|
|
1844
|
+
onReady: (event) => emit("ready", event),
|
|
1694
1845
|
onPlay: () => emit("play"),
|
|
1695
1846
|
onPause: () => emit("pause"),
|
|
1696
1847
|
onEnd: () => emit("end"),
|
|
1697
|
-
onError: (
|
|
1698
|
-
onProgress: (
|
|
1848
|
+
onError: (event) => emit("error", event),
|
|
1849
|
+
onProgress: (event) => emit("progress", event)
|
|
1699
1850
|
});
|
|
1700
1851
|
}
|
|
1701
1852
|
});
|
|
1702
1853
|
|
|
1703
|
-
// src/
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1854
|
+
// src/components/VFlatList.ts
|
|
1855
|
+
import { defineComponent as defineComponent28, h as h28, ref as ref5, computed as computed2 } from "@vue/runtime-core";
|
|
1856
|
+
function getDefaultItemKey(item, index) {
|
|
1857
|
+
if (typeof item === "object" && item !== null) {
|
|
1858
|
+
const keyedItem = item;
|
|
1859
|
+
return keyedItem.id ?? keyedItem.key ?? index;
|
|
1860
|
+
}
|
|
1861
|
+
return index;
|
|
1862
|
+
}
|
|
1863
|
+
function resolveFlexValue(style) {
|
|
1864
|
+
return typeof style?.flex === "number" ? style.flex : 1;
|
|
1865
|
+
}
|
|
1866
|
+
var VFlatList = defineComponent28({
|
|
1867
|
+
name: "VFlatList",
|
|
1868
|
+
props: {
|
|
1869
|
+
/** Array of data items to render. */
|
|
1870
|
+
data: {
|
|
1871
|
+
type: Array,
|
|
1872
|
+
required: true
|
|
1873
|
+
},
|
|
1874
|
+
/**
|
|
1875
|
+
* Render function for each item. Receives { item, index } and returns a VNode.
|
|
1876
|
+
* If not provided, the `#item` slot is used instead.
|
|
1877
|
+
*/
|
|
1878
|
+
renderItem: {
|
|
1879
|
+
type: Function,
|
|
1880
|
+
default: void 0
|
|
1881
|
+
},
|
|
1882
|
+
/** Extract a unique key from each item. Defaults to item.id, item.key, or index. */
|
|
1883
|
+
keyExtractor: {
|
|
1884
|
+
type: Function,
|
|
1885
|
+
default: getDefaultItemKey
|
|
1886
|
+
},
|
|
1887
|
+
/** Fixed height for each item in points. Required for virtualization math. */
|
|
1888
|
+
itemHeight: {
|
|
1889
|
+
type: Number,
|
|
1890
|
+
required: true
|
|
1891
|
+
},
|
|
1892
|
+
/**
|
|
1893
|
+
* Number of viewport-heights to render above and below the visible area.
|
|
1894
|
+
* Higher values reduce blank flashes during fast scrolling but use more memory.
|
|
1895
|
+
* Default: 3 (3 viewports above + 3 below = 7 total viewports of items).
|
|
1896
|
+
*/
|
|
1897
|
+
windowSize: {
|
|
1898
|
+
type: Number,
|
|
1899
|
+
default: 3
|
|
1900
|
+
},
|
|
1901
|
+
/** Style for the outer scroll container. */
|
|
1902
|
+
style: {
|
|
1903
|
+
type: Object,
|
|
1904
|
+
default: () => ({})
|
|
1905
|
+
},
|
|
1906
|
+
/** Show vertical scroll indicator. Default: true */
|
|
1907
|
+
showsScrollIndicator: {
|
|
1908
|
+
type: Boolean,
|
|
1909
|
+
default: true
|
|
1910
|
+
},
|
|
1911
|
+
/** Enable bounce at scroll boundaries. Default: true */
|
|
1912
|
+
bounces: {
|
|
1913
|
+
type: Boolean,
|
|
1914
|
+
default: true
|
|
1915
|
+
},
|
|
1916
|
+
/** Height of the header slot in points. Used to offset items below the header. */
|
|
1917
|
+
headerHeight: {
|
|
1918
|
+
type: Number,
|
|
1919
|
+
default: 0
|
|
1920
|
+
},
|
|
1921
|
+
/**
|
|
1922
|
+
* How far from the end (in viewport fractions) to trigger endReached.
|
|
1923
|
+
* Default: 0.5 (trigger when within 50% of a viewport from the bottom).
|
|
1924
|
+
*/
|
|
1925
|
+
endReachedThreshold: {
|
|
1926
|
+
type: Number,
|
|
1927
|
+
default: 0.5
|
|
1928
|
+
}
|
|
1707
1929
|
},
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1930
|
+
emits: ["scroll", "endReached"],
|
|
1931
|
+
setup(props, { slots, emit }) {
|
|
1932
|
+
const scrollOffset = ref5(0);
|
|
1933
|
+
const viewportHeight = ref5(0);
|
|
1934
|
+
let endReachedFired = false;
|
|
1935
|
+
const hasHeader = computed2(() => !!slots.header);
|
|
1936
|
+
const totalHeight = computed2(() => {
|
|
1937
|
+
const itemsHeight = (props.data?.length ?? 0) * props.itemHeight;
|
|
1938
|
+
return itemsHeight + (hasHeader.value ? props.headerHeight : 0);
|
|
1939
|
+
});
|
|
1940
|
+
const visibleRange = computed2(() => {
|
|
1941
|
+
const vh = viewportHeight.value || props.itemHeight * 20;
|
|
1942
|
+
const buffer = vh * props.windowSize;
|
|
1943
|
+
const startPx = Math.max(0, scrollOffset.value - buffer);
|
|
1944
|
+
const endPx = scrollOffset.value + vh + buffer;
|
|
1945
|
+
const startIdx = Math.floor(startPx / props.itemHeight);
|
|
1946
|
+
const endIdx = Math.min(
|
|
1947
|
+
Math.ceil(endPx / props.itemHeight),
|
|
1948
|
+
props.data?.length ?? 0
|
|
1949
|
+
);
|
|
1950
|
+
return { start: startIdx, end: endIdx };
|
|
1951
|
+
});
|
|
1952
|
+
function onScroll(event) {
|
|
1953
|
+
scrollOffset.value = event.y ?? 0;
|
|
1954
|
+
if (event.layoutHeight && event.layoutHeight > 0) {
|
|
1955
|
+
viewportHeight.value = event.layoutHeight;
|
|
1956
|
+
}
|
|
1957
|
+
emit("scroll", event);
|
|
1958
|
+
const contentLength = totalHeight.value;
|
|
1959
|
+
const offset = scrollOffset.value;
|
|
1960
|
+
const vh = viewportHeight.value || props.itemHeight * 20;
|
|
1961
|
+
const distanceFromEnd = contentLength - vh - offset;
|
|
1962
|
+
const threshold = vh * props.endReachedThreshold;
|
|
1963
|
+
if (distanceFromEnd < threshold && !endReachedFired) {
|
|
1964
|
+
endReachedFired = true;
|
|
1965
|
+
emit("endReached");
|
|
1966
|
+
} else if (distanceFromEnd >= threshold) {
|
|
1967
|
+
endReachedFired = false;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
return () => {
|
|
1971
|
+
const items = props.data ?? [];
|
|
1972
|
+
const { start, end } = visibleRange.value;
|
|
1973
|
+
const children = [];
|
|
1974
|
+
for (let i = start; i < end; i++) {
|
|
1975
|
+
const item = items[i];
|
|
1976
|
+
if (item === void 0) continue;
|
|
1977
|
+
const key = props.keyExtractor(item, i);
|
|
1978
|
+
const itemContent = props.renderItem ? [props.renderItem({ item, index: i })] : slots.item?.({ item, index: i }) ?? [];
|
|
1979
|
+
children.push(
|
|
1980
|
+
h28(
|
|
1981
|
+
"VView",
|
|
1982
|
+
{
|
|
1983
|
+
key,
|
|
1984
|
+
style: {
|
|
1985
|
+
position: "absolute",
|
|
1986
|
+
top: (hasHeader.value ? props.headerHeight : 0) + i * props.itemHeight,
|
|
1987
|
+
left: 0,
|
|
1988
|
+
right: 0,
|
|
1989
|
+
height: props.itemHeight
|
|
1990
|
+
}
|
|
1991
|
+
},
|
|
1992
|
+
itemContent
|
|
1993
|
+
)
|
|
1994
|
+
);
|
|
1995
|
+
}
|
|
1996
|
+
if (slots.header) {
|
|
1997
|
+
children.unshift(
|
|
1998
|
+
h28("VView", { key: "__vfl_header__", style: { position: "absolute", top: 0, left: 0, right: 0 } }, slots.header())
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
if (items.length === 0 && slots.empty) {
|
|
2002
|
+
return h28(
|
|
2003
|
+
"VScrollView",
|
|
2004
|
+
{
|
|
2005
|
+
style: { ...props.style, flex: resolveFlexValue(props.style) },
|
|
2006
|
+
showsVerticalScrollIndicator: props.showsScrollIndicator,
|
|
2007
|
+
bounces: props.bounces
|
|
2008
|
+
},
|
|
2009
|
+
[h28("VView", { style: { flex: 1 } }, slots.empty())]
|
|
2010
|
+
);
|
|
2011
|
+
}
|
|
2012
|
+
const innerContainer = h28(
|
|
2013
|
+
"VView",
|
|
2014
|
+
{
|
|
2015
|
+
key: "__vfl_container__",
|
|
2016
|
+
style: {
|
|
2017
|
+
height: totalHeight.value,
|
|
2018
|
+
width: "100%"
|
|
2019
|
+
}
|
|
2020
|
+
},
|
|
2021
|
+
children
|
|
2022
|
+
);
|
|
2023
|
+
return h28(
|
|
2024
|
+
"VScrollView",
|
|
2025
|
+
{
|
|
2026
|
+
style: { ...props.style, flex: resolveFlexValue(props.style) },
|
|
2027
|
+
showsVerticalScrollIndicator: props.showsScrollIndicator,
|
|
2028
|
+
bounces: props.bounces,
|
|
2029
|
+
onScroll
|
|
2030
|
+
},
|
|
2031
|
+
[innerContainer]
|
|
2032
|
+
);
|
|
2033
|
+
};
|
|
1711
2034
|
}
|
|
1712
|
-
};
|
|
2035
|
+
});
|
|
1713
2036
|
|
|
1714
|
-
// src/
|
|
1715
|
-
import { defineComponent as
|
|
1716
|
-
var
|
|
1717
|
-
name: "
|
|
2037
|
+
// src/components/VTabBar.ts
|
|
2038
|
+
import { defineComponent as defineComponent29, h as h29, ref as ref6, watch as watch4 } from "@vue/runtime-core";
|
|
2039
|
+
var VTabBar = defineComponent29({
|
|
2040
|
+
name: "VTabBar",
|
|
1718
2041
|
props: {
|
|
1719
|
-
|
|
1720
|
-
|
|
2042
|
+
/** Array of tab configurations */
|
|
2043
|
+
tabs: {
|
|
1721
2044
|
type: Array,
|
|
1722
|
-
|
|
2045
|
+
required: true
|
|
2046
|
+
},
|
|
2047
|
+
/** Currently active tab ID */
|
|
2048
|
+
activeTab: {
|
|
2049
|
+
type: String,
|
|
2050
|
+
required: true
|
|
2051
|
+
},
|
|
2052
|
+
/** Position: 'top' | 'bottom' */
|
|
2053
|
+
position: {
|
|
2054
|
+
type: String,
|
|
2055
|
+
default: "bottom"
|
|
1723
2056
|
}
|
|
1724
2057
|
},
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
const
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
error.value = normalizedError;
|
|
1731
|
-
errorInfo.value = info;
|
|
1732
|
-
if (props.onError) {
|
|
1733
|
-
props.onError(normalizedError, info);
|
|
1734
|
-
}
|
|
1735
|
-
return false;
|
|
2058
|
+
emits: ["change"],
|
|
2059
|
+
setup(props, { emit }) {
|
|
2060
|
+
const activeTab = ref6(props.activeTab);
|
|
2061
|
+
watch4(() => props.activeTab, (newVal) => {
|
|
2062
|
+
activeTab.value = newVal;
|
|
1736
2063
|
});
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
2064
|
+
const switchTab = (tabId) => {
|
|
2065
|
+
activeTab.value = tabId;
|
|
2066
|
+
emit("change", tabId);
|
|
2067
|
+
};
|
|
2068
|
+
return () => h29(VView, {
|
|
2069
|
+
style: {
|
|
2070
|
+
position: "absolute",
|
|
2071
|
+
[props.position]: 0,
|
|
2072
|
+
left: 0,
|
|
2073
|
+
right: 0,
|
|
2074
|
+
backgroundColor: "#fff",
|
|
2075
|
+
borderTopWidth: 1,
|
|
2076
|
+
borderTopColor: "#e0e0e0",
|
|
2077
|
+
flexDirection: "row",
|
|
2078
|
+
height: 60
|
|
2079
|
+
}
|
|
2080
|
+
}, () => props.tabs.map((tab) => {
|
|
2081
|
+
const isActive = activeTab.value === tab.id;
|
|
2082
|
+
return h29(VPressable, {
|
|
2083
|
+
key: tab.id,
|
|
2084
|
+
style: {
|
|
2085
|
+
flex: 1,
|
|
2086
|
+
justifyContent: "center",
|
|
2087
|
+
alignItems: "center"
|
|
2088
|
+
},
|
|
2089
|
+
onPress: () => switchTab(tab.id),
|
|
2090
|
+
accessibilityLabel: tab.label,
|
|
2091
|
+
accessibilityRole: "tab",
|
|
2092
|
+
accessibilityState: { selected: isActive }
|
|
2093
|
+
}, () => [
|
|
2094
|
+
tab.icon ? h29(VText, { style: { fontSize: 24, marginBottom: 4 } }, () => tab.icon) : null,
|
|
2095
|
+
h29(VText, {
|
|
2096
|
+
style: {
|
|
2097
|
+
fontSize: 12,
|
|
2098
|
+
fontWeight: isActive ? "600" : "400",
|
|
2099
|
+
color: isActive ? "#007AFF" : "#8E8E93"
|
|
2100
|
+
}
|
|
2101
|
+
}, () => tab.label),
|
|
2102
|
+
tab.badge ? h29(VView, {
|
|
2103
|
+
style: {
|
|
2104
|
+
position: "absolute",
|
|
2105
|
+
top: 8,
|
|
2106
|
+
right: "25%",
|
|
2107
|
+
backgroundColor: "#FF3B30",
|
|
2108
|
+
borderRadius: 10,
|
|
2109
|
+
minWidth: 20,
|
|
2110
|
+
height: 20,
|
|
2111
|
+
justifyContent: "center",
|
|
2112
|
+
alignItems: "center"
|
|
2113
|
+
}
|
|
2114
|
+
}, () => h29(VText, {
|
|
2115
|
+
style: {
|
|
2116
|
+
color: "#fff",
|
|
2117
|
+
fontSize: 12,
|
|
2118
|
+
fontWeight: "600",
|
|
2119
|
+
paddingHorizontal: 6
|
|
2120
|
+
}
|
|
2121
|
+
}, () => String(tab.badge))) : null
|
|
2122
|
+
]);
|
|
2123
|
+
}));
|
|
2124
|
+
}
|
|
2125
|
+
});
|
|
2126
|
+
|
|
2127
|
+
// src/components/VDrawer.ts
|
|
2128
|
+
import { defineComponent as defineComponent30, h as h30, inject, provide, ref as ref7, watch as watch5 } from "@vue/runtime-core";
|
|
2129
|
+
var drawerContextKey = /* @__PURE__ */ Symbol("VDrawerContext");
|
|
2130
|
+
var VDrawer = defineComponent30({
|
|
2131
|
+
name: "VDrawer",
|
|
2132
|
+
props: {
|
|
2133
|
+
/** Whether the drawer is open */
|
|
2134
|
+
open: {
|
|
2135
|
+
type: Boolean,
|
|
2136
|
+
default: false
|
|
2137
|
+
},
|
|
2138
|
+
/** Drawer position: 'left' | 'right' */
|
|
2139
|
+
position: {
|
|
2140
|
+
type: String,
|
|
2141
|
+
default: "left"
|
|
2142
|
+
},
|
|
2143
|
+
/** Drawer width */
|
|
2144
|
+
width: {
|
|
2145
|
+
type: Number,
|
|
2146
|
+
default: 280
|
|
2147
|
+
},
|
|
2148
|
+
/** Close on item press */
|
|
2149
|
+
closeOnPress: {
|
|
2150
|
+
type: Boolean,
|
|
2151
|
+
default: true
|
|
1740
2152
|
}
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
2153
|
+
},
|
|
2154
|
+
emits: ["update:open", "close"],
|
|
2155
|
+
setup(props, { attrs, slots, emit }) {
|
|
2156
|
+
const isOpen = ref7(props.open);
|
|
2157
|
+
watch5(() => props.open, (value) => {
|
|
2158
|
+
isOpen.value = value;
|
|
2159
|
+
});
|
|
2160
|
+
const closeDrawer = () => {
|
|
2161
|
+
isOpen.value = false;
|
|
2162
|
+
emit("update:open", false);
|
|
2163
|
+
emit("close");
|
|
2164
|
+
};
|
|
2165
|
+
provide(drawerContextKey, {
|
|
2166
|
+
close: closeDrawer,
|
|
2167
|
+
shouldCloseOnPress: () => props.closeOnPress
|
|
2168
|
+
});
|
|
1750
2169
|
return () => {
|
|
1751
|
-
if (
|
|
1752
|
-
return
|
|
2170
|
+
if (!isOpen.value && !slots.default) {
|
|
2171
|
+
return null;
|
|
2172
|
+
}
|
|
2173
|
+
const overlayStyle = {
|
|
2174
|
+
position: "absolute",
|
|
2175
|
+
top: 0,
|
|
2176
|
+
left: 0,
|
|
2177
|
+
right: 0,
|
|
2178
|
+
bottom: 0,
|
|
2179
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
2180
|
+
opacity: isOpen.value ? 1 : 0,
|
|
2181
|
+
zIndex: 999
|
|
2182
|
+
};
|
|
2183
|
+
const drawerStyle = {
|
|
2184
|
+
position: "absolute",
|
|
2185
|
+
top: 0,
|
|
2186
|
+
[props.position]: 0,
|
|
2187
|
+
width: props.width,
|
|
2188
|
+
height: "100%",
|
|
2189
|
+
backgroundColor: "#fff",
|
|
2190
|
+
transform: [
|
|
2191
|
+
{ translateX: isOpen.value ? 0 : props.position === "left" ? -props.width : props.width }
|
|
2192
|
+
],
|
|
2193
|
+
zIndex: 1e3
|
|
2194
|
+
};
|
|
2195
|
+
const drawerProps = {
|
|
2196
|
+
...attrs,
|
|
2197
|
+
style: {
|
|
2198
|
+
...drawerStyle,
|
|
2199
|
+
...attrs.style && typeof attrs.style === "object" && !Array.isArray(attrs.style) ? attrs.style : {}
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
const drawerChildren = [];
|
|
2203
|
+
if (slots.header) {
|
|
2204
|
+
drawerChildren.push(...slots.header());
|
|
2205
|
+
}
|
|
2206
|
+
if (slots.default) {
|
|
2207
|
+
drawerChildren.push(...slots.default({ close: closeDrawer }) ?? []);
|
|
2208
|
+
}
|
|
2209
|
+
return [
|
|
2210
|
+
// Overlay
|
|
2211
|
+
isOpen.value ? h30(VPressable, {
|
|
2212
|
+
style: overlayStyle,
|
|
2213
|
+
onPress: closeDrawer,
|
|
2214
|
+
accessibilityLabel: "Close menu"
|
|
2215
|
+
}) : null,
|
|
2216
|
+
// Drawer
|
|
2217
|
+
h30(VView, drawerProps, () => drawerChildren)
|
|
2218
|
+
];
|
|
2219
|
+
};
|
|
2220
|
+
}
|
|
2221
|
+
});
|
|
2222
|
+
var VDrawerItem = defineComponent30({
|
|
2223
|
+
name: "VDrawerItem",
|
|
2224
|
+
props: {
|
|
2225
|
+
/** Icon (emoji or icon name) */
|
|
2226
|
+
icon: {
|
|
2227
|
+
type: String,
|
|
2228
|
+
default: ""
|
|
2229
|
+
},
|
|
2230
|
+
/** Label text */
|
|
2231
|
+
label: {
|
|
2232
|
+
type: String,
|
|
2233
|
+
required: true
|
|
2234
|
+
},
|
|
2235
|
+
/** Badge count */
|
|
2236
|
+
badge: {
|
|
2237
|
+
type: [Number, String],
|
|
2238
|
+
default: null
|
|
2239
|
+
},
|
|
2240
|
+
/** Disabled state */
|
|
2241
|
+
disabled: {
|
|
2242
|
+
type: Boolean,
|
|
2243
|
+
default: false
|
|
2244
|
+
}
|
|
2245
|
+
},
|
|
2246
|
+
emits: ["press"],
|
|
2247
|
+
setup(props, { slots, emit }) {
|
|
2248
|
+
const drawer = inject(drawerContextKey, null);
|
|
2249
|
+
const handlePress = () => {
|
|
2250
|
+
if (props.disabled) return;
|
|
2251
|
+
emit("press");
|
|
2252
|
+
if (drawer?.shouldCloseOnPress()) {
|
|
2253
|
+
drawer.close();
|
|
1753
2254
|
}
|
|
1754
|
-
return slots.default?.();
|
|
1755
2255
|
};
|
|
2256
|
+
return () => h30(VPressable, {
|
|
2257
|
+
style: {
|
|
2258
|
+
flexDirection: "row",
|
|
2259
|
+
alignItems: "center",
|
|
2260
|
+
padding: 16,
|
|
2261
|
+
borderBottomWidth: 1,
|
|
2262
|
+
borderBottomColor: "#f0f0f0",
|
|
2263
|
+
opacity: props.disabled ? 0.5 : 1
|
|
2264
|
+
},
|
|
2265
|
+
onPress: handlePress,
|
|
2266
|
+
disabled: props.disabled,
|
|
2267
|
+
accessibilityLabel: props.label,
|
|
2268
|
+
accessibilityRole: "menuitem",
|
|
2269
|
+
accessibilityState: { disabled: props.disabled }
|
|
2270
|
+
}, () => {
|
|
2271
|
+
const children = [];
|
|
2272
|
+
if (props.icon) {
|
|
2273
|
+
children.push(
|
|
2274
|
+
h30(VText, {
|
|
2275
|
+
style: {
|
|
2276
|
+
fontSize: 24,
|
|
2277
|
+
marginRight: 16,
|
|
2278
|
+
width: 32,
|
|
2279
|
+
textAlign: "center"
|
|
2280
|
+
}
|
|
2281
|
+
}, () => props.icon)
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2284
|
+
children.push(
|
|
2285
|
+
h30(VText, {
|
|
2286
|
+
style: {
|
|
2287
|
+
flex: 1,
|
|
2288
|
+
fontSize: 16,
|
|
2289
|
+
color: props.disabled ? "#999" : "#333"
|
|
2290
|
+
}
|
|
2291
|
+
}, () => props.label)
|
|
2292
|
+
);
|
|
2293
|
+
if (props.badge) {
|
|
2294
|
+
children.push(
|
|
2295
|
+
h30(VView, {
|
|
2296
|
+
style: {
|
|
2297
|
+
backgroundColor: "#007AFF",
|
|
2298
|
+
borderRadius: 12,
|
|
2299
|
+
minWidth: 24,
|
|
2300
|
+
height: 24,
|
|
2301
|
+
justifyContent: "center",
|
|
2302
|
+
alignItems: "center",
|
|
2303
|
+
paddingHorizontal: 8
|
|
2304
|
+
}
|
|
2305
|
+
}, () => h30(VText, {
|
|
2306
|
+
style: {
|
|
2307
|
+
color: "#fff",
|
|
2308
|
+
fontSize: 12,
|
|
2309
|
+
fontWeight: "600"
|
|
2310
|
+
}
|
|
2311
|
+
}, () => String(props.badge)))
|
|
2312
|
+
);
|
|
2313
|
+
}
|
|
2314
|
+
if (slots.default) {
|
|
2315
|
+
children.push(...slots.default() ?? []);
|
|
2316
|
+
}
|
|
2317
|
+
return children;
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
});
|
|
2321
|
+
var VDrawerSection = defineComponent30({
|
|
2322
|
+
name: "VDrawerSection",
|
|
2323
|
+
props: {
|
|
2324
|
+
/** Section title */
|
|
2325
|
+
title: {
|
|
2326
|
+
type: String,
|
|
2327
|
+
default: ""
|
|
2328
|
+
}
|
|
2329
|
+
},
|
|
2330
|
+
setup(props, { slots }) {
|
|
2331
|
+
return () => h30(VView, {
|
|
2332
|
+
style: {
|
|
2333
|
+
paddingVertical: 8,
|
|
2334
|
+
paddingHorizontal: 16,
|
|
2335
|
+
backgroundColor: "#f9f9f9",
|
|
2336
|
+
borderBottomWidth: 1,
|
|
2337
|
+
borderBottomColor: "#e0e0e0"
|
|
2338
|
+
}
|
|
2339
|
+
}, () => {
|
|
2340
|
+
const children = [];
|
|
2341
|
+
if (props.title) {
|
|
2342
|
+
children.push(
|
|
2343
|
+
h30(VText, {
|
|
2344
|
+
style: {
|
|
2345
|
+
fontSize: 13,
|
|
2346
|
+
fontWeight: "600",
|
|
2347
|
+
color: "#666",
|
|
2348
|
+
textTransform: "uppercase",
|
|
2349
|
+
letterSpacing: 0.5
|
|
2350
|
+
}
|
|
2351
|
+
}, () => props.title)
|
|
2352
|
+
);
|
|
2353
|
+
}
|
|
2354
|
+
if (slots.default) {
|
|
2355
|
+
children.push(...slots.default() ?? []);
|
|
2356
|
+
}
|
|
2357
|
+
return children;
|
|
2358
|
+
});
|
|
1756
2359
|
}
|
|
1757
2360
|
});
|
|
2361
|
+
VDrawer.Item = VDrawerItem;
|
|
2362
|
+
VDrawer.Section = VDrawerSection;
|
|
1758
2363
|
|
|
1759
|
-
// src/
|
|
1760
|
-
|
|
2364
|
+
// src/components/VTransition.ts
|
|
2365
|
+
import { defineComponent as defineComponent31, h as h31, ref as ref8 } from "@vue/runtime-core";
|
|
1761
2366
|
|
|
1762
|
-
// src/
|
|
1763
|
-
var
|
|
1764
|
-
|
|
1765
|
-
"
|
|
1766
|
-
"
|
|
1767
|
-
"
|
|
1768
|
-
"
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
"
|
|
2367
|
+
// src/composables/useAnimation.ts
|
|
2368
|
+
var Easing = {
|
|
2369
|
+
linear: "linear",
|
|
2370
|
+
ease: "ease",
|
|
2371
|
+
easeIn: "easeIn",
|
|
2372
|
+
easeOut: "easeOut",
|
|
2373
|
+
easeInOut: "easeInOut"
|
|
2374
|
+
};
|
|
2375
|
+
function hasViewId(value) {
|
|
2376
|
+
return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
|
|
2377
|
+
}
|
|
2378
|
+
function isAnimationRef(target) {
|
|
2379
|
+
return typeof target === "object" && target !== null && "value" in target;
|
|
2380
|
+
}
|
|
2381
|
+
function resolveViewId(target) {
|
|
2382
|
+
if (typeof target === "number") return target;
|
|
2383
|
+
if (isAnimationRef(target)) {
|
|
2384
|
+
const val = target.value;
|
|
2385
|
+
if (hasViewId(val)) return val.id;
|
|
2386
|
+
throw new Error("[VueNative] Animation target ref has no .value.id \u2014 is the ref attached to a component?");
|
|
2387
|
+
}
|
|
2388
|
+
if (hasViewId(target)) return target.id;
|
|
2389
|
+
throw new Error("[VueNative] Invalid animation target. Pass a number, template ref, or NativeNode.");
|
|
2390
|
+
}
|
|
2391
|
+
function useAnimation() {
|
|
2392
|
+
function timing(target, toStyles, config = {}) {
|
|
2393
|
+
return NativeBridge.invokeNativeModule("Animation", "timing", [resolveViewId(target), toStyles, config]);
|
|
2394
|
+
}
|
|
2395
|
+
function spring(target, toStyles, config = {}) {
|
|
2396
|
+
return NativeBridge.invokeNativeModule("Animation", "spring", [resolveViewId(target), toStyles, config]);
|
|
2397
|
+
}
|
|
2398
|
+
function keyframe(target, steps, config = {}) {
|
|
2399
|
+
return NativeBridge.invokeNativeModule("Animation", "keyframe", [resolveViewId(target), steps, config]);
|
|
2400
|
+
}
|
|
2401
|
+
function sequence(animations) {
|
|
2402
|
+
return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
|
|
2403
|
+
}
|
|
2404
|
+
function parallel(animations) {
|
|
2405
|
+
return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
|
|
2406
|
+
}
|
|
2407
|
+
function fadeOut(target, duration = 300) {
|
|
2408
|
+
return timing(target, { opacity: 0 }, { duration });
|
|
2409
|
+
}
|
|
2410
|
+
function fadeIn(target, duration = 300) {
|
|
2411
|
+
return timing(target, { opacity: 1 }, { duration });
|
|
2412
|
+
}
|
|
2413
|
+
function slideInFromRight(target, duration = 300) {
|
|
2414
|
+
return timing(target, { translateX: 0 }, { duration, easing: "easeOut" });
|
|
2415
|
+
}
|
|
2416
|
+
function slideOutToRight(target, duration = 300) {
|
|
2417
|
+
return timing(target, { translateX: 400 }, { duration, easing: "easeIn" });
|
|
2418
|
+
}
|
|
2419
|
+
function resolveId(target) {
|
|
2420
|
+
return resolveViewId(target);
|
|
2421
|
+
}
|
|
2422
|
+
return {
|
|
2423
|
+
timing,
|
|
2424
|
+
spring,
|
|
2425
|
+
keyframe,
|
|
2426
|
+
sequence,
|
|
2427
|
+
parallel,
|
|
2428
|
+
fadeIn,
|
|
2429
|
+
fadeOut,
|
|
2430
|
+
slideInFromRight,
|
|
2431
|
+
slideOutToRight,
|
|
2432
|
+
resolveId,
|
|
2433
|
+
Easing
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
|
|
2437
|
+
// src/components/VTransition.ts
|
|
2438
|
+
var DefaultDuration = 300;
|
|
2439
|
+
function resolveAnimationTarget(el) {
|
|
2440
|
+
if (!el) return void 0;
|
|
2441
|
+
if (typeof el === "number") return el;
|
|
2442
|
+
if (typeof el === "object" && "id" in el) return el.id;
|
|
2443
|
+
return void 0;
|
|
2444
|
+
}
|
|
2445
|
+
var VTransition = defineComponent31({
|
|
2446
|
+
name: "VTransition",
|
|
2447
|
+
props: {
|
|
2448
|
+
name: { type: String, default: "" },
|
|
2449
|
+
appear: { type: Boolean, default: false },
|
|
2450
|
+
persist: { type: Boolean, default: false },
|
|
2451
|
+
mode: { type: String, default: "default" },
|
|
2452
|
+
css: { type: Boolean, default: true },
|
|
2453
|
+
type: { type: String, default: "transition" },
|
|
2454
|
+
enterClass: { type: String, default: "" },
|
|
2455
|
+
leaveClass: { type: String, default: "" },
|
|
2456
|
+
enterActiveClass: { type: String, default: "" },
|
|
2457
|
+
leaveActiveClass: { type: String, default: "" },
|
|
2458
|
+
enterToClass: { type: String, default: "" },
|
|
2459
|
+
leaveToClass: { type: String, default: "" },
|
|
2460
|
+
enterFromClass: { type: String, default: "" },
|
|
2461
|
+
leaveFromClass: { type: String, default: "" },
|
|
2462
|
+
appearClass: { type: String, default: "" },
|
|
2463
|
+
appearActiveClass: { type: String, default: "" },
|
|
2464
|
+
appearToClass: { type: String, default: "" },
|
|
2465
|
+
duration: [Number, Object]
|
|
2466
|
+
},
|
|
2467
|
+
setup(transitionProps, { slots, expose }) {
|
|
2468
|
+
const { timing } = useAnimation();
|
|
2469
|
+
const isAppearing = ref8(false);
|
|
2470
|
+
const isLeaving = ref8(false);
|
|
2471
|
+
const hasEntered = ref8(!transitionProps.appear);
|
|
2472
|
+
function getElementFromVNode(vnode) {
|
|
2473
|
+
try {
|
|
2474
|
+
const el = vnode.el;
|
|
2475
|
+
if (!el) return void 0;
|
|
2476
|
+
return resolveAnimationTarget(el);
|
|
2477
|
+
} catch {
|
|
2478
|
+
return void 0;
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
async function doEnter(el) {
|
|
2482
|
+
const viewId = getElementFromVNode(el);
|
|
2483
|
+
if (!viewId) return;
|
|
2484
|
+
isAppearing.value = true;
|
|
2485
|
+
const enterDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.enter ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
|
|
2486
|
+
const enterStyles = { opacity: 1 };
|
|
2487
|
+
try {
|
|
2488
|
+
await timing(viewId, { opacity: 0 }, { duration: 0 });
|
|
2489
|
+
await timing(viewId, enterStyles, { duration: enterDuration, easing: "easeOut" });
|
|
2490
|
+
isAppearing.value = false;
|
|
2491
|
+
hasEntered.value = true;
|
|
2492
|
+
} catch (e) {
|
|
2493
|
+
console.warn("[VueNative Transition] enter animation failed:", e);
|
|
2494
|
+
isAppearing.value = false;
|
|
2495
|
+
hasEntered.value = true;
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
async function doLeave(el) {
|
|
2499
|
+
const viewId = getElementFromVNode(el);
|
|
2500
|
+
if (!viewId) return;
|
|
2501
|
+
isLeaving.value = true;
|
|
2502
|
+
const leaveDuration = typeof transitionProps.duration === "object" ? transitionProps.duration.leave ?? DefaultDuration : transitionProps.duration ?? DefaultDuration;
|
|
2503
|
+
try {
|
|
2504
|
+
await timing(viewId, { opacity: 0 }, { duration: leaveDuration, easing: "easeIn" });
|
|
2505
|
+
} catch (e) {
|
|
2506
|
+
console.warn("[VueNative Transition] leave animation failed:", e);
|
|
2507
|
+
} finally {
|
|
2508
|
+
isLeaving.value = false;
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
function onEnter(_el, done) {
|
|
2512
|
+
if (!hasEntered.value || transitionProps.appear) {
|
|
2513
|
+
doEnter(_el).then(() => done());
|
|
2514
|
+
} else {
|
|
2515
|
+
done();
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
function onLeave(el, done) {
|
|
2519
|
+
doLeave(el).then(() => done());
|
|
2520
|
+
}
|
|
2521
|
+
function onAfterEnter() {
|
|
2522
|
+
}
|
|
2523
|
+
function onAfterLeave() {
|
|
2524
|
+
}
|
|
2525
|
+
function onEnterCancelled() {
|
|
2526
|
+
isAppearing.value = false;
|
|
2527
|
+
}
|
|
2528
|
+
function onLeaveCancelled() {
|
|
2529
|
+
isLeaving.value = false;
|
|
2530
|
+
}
|
|
2531
|
+
function onAppear(el, done) {
|
|
2532
|
+
isAppearing.value = true;
|
|
2533
|
+
doEnter(el).then(() => done());
|
|
2534
|
+
}
|
|
2535
|
+
function onAfterAppear() {
|
|
2536
|
+
isAppearing.value = false;
|
|
2537
|
+
}
|
|
2538
|
+
expose({
|
|
2539
|
+
onEnter,
|
|
2540
|
+
onLeave,
|
|
2541
|
+
onAfterEnter,
|
|
2542
|
+
onAfterLeave,
|
|
2543
|
+
onEnterCancelled,
|
|
2544
|
+
onLeaveCancelled,
|
|
2545
|
+
onAppear,
|
|
2546
|
+
onAfterAppear,
|
|
2547
|
+
isAppearing,
|
|
2548
|
+
isLeaving,
|
|
2549
|
+
hasEntered
|
|
2550
|
+
});
|
|
2551
|
+
return () => {
|
|
2552
|
+
const children = slots.default?.() ?? [];
|
|
2553
|
+
const hasDefault = children.length > 0;
|
|
2554
|
+
if (!hasDefault) {
|
|
2555
|
+
return h31("", {}, []);
|
|
2556
|
+
}
|
|
2557
|
+
let finalChildren = children;
|
|
2558
|
+
if (transitionProps.mode === "out-in") {
|
|
2559
|
+
if (isLeaving.value) {
|
|
2560
|
+
finalChildren = [children[children.length - 1]];
|
|
2561
|
+
} else if (!hasEntered.value) {
|
|
2562
|
+
finalChildren = [];
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
if (transitionProps.mode === "in-out") {
|
|
2566
|
+
if (isAppearing.value && children.length > 1) {
|
|
2567
|
+
finalChildren = [children[0]];
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
return h31("Transition", {
|
|
2571
|
+
name: transitionProps.name || "v",
|
|
2572
|
+
appear: transitionProps.appear,
|
|
2573
|
+
persist: transitionProps.persist || transitionProps.name === "persist",
|
|
2574
|
+
css: transitionProps.css,
|
|
2575
|
+
type: transitionProps.type,
|
|
2576
|
+
onEnter,
|
|
2577
|
+
onLeave,
|
|
2578
|
+
onAfterEnter,
|
|
2579
|
+
onAfterLeave,
|
|
2580
|
+
onEnterCancelled,
|
|
2581
|
+
onLeaveCancelled,
|
|
2582
|
+
onAppear,
|
|
2583
|
+
onAfterAppear
|
|
2584
|
+
}, () => finalChildren);
|
|
2585
|
+
};
|
|
2586
|
+
}
|
|
2587
|
+
});
|
|
2588
|
+
var VTransitionGroup = defineComponent31({
|
|
2589
|
+
name: "VTransitionGroup",
|
|
2590
|
+
props: {
|
|
2591
|
+
tag: { type: String, default: void 0 },
|
|
2592
|
+
name: { type: String, default: "v" },
|
|
2593
|
+
appear: { type: Boolean, default: false },
|
|
2594
|
+
persist: { type: Boolean, default: false },
|
|
2595
|
+
moveClass: { type: String, default: "" },
|
|
2596
|
+
duration: { type: Number, default: void 0 }
|
|
2597
|
+
},
|
|
2598
|
+
setup(groupProps, { slots, expose }) {
|
|
2599
|
+
const { timing } = useAnimation();
|
|
2600
|
+
function onMove(_el) {
|
|
2601
|
+
}
|
|
2602
|
+
function onEnter(el, done) {
|
|
2603
|
+
const viewId = resolveAnimationTarget(el);
|
|
2604
|
+
if (!viewId) {
|
|
2605
|
+
done();
|
|
2606
|
+
return;
|
|
2607
|
+
}
|
|
2608
|
+
timing(viewId, { opacity: 1 }, { duration: groupProps.duration ?? 300, easing: "easeOut" }).then(() => done()).catch(() => done());
|
|
2609
|
+
}
|
|
2610
|
+
function onLeave(el, done) {
|
|
2611
|
+
const viewId = resolveAnimationTarget(el);
|
|
2612
|
+
if (!viewId) {
|
|
2613
|
+
done();
|
|
2614
|
+
return;
|
|
2615
|
+
}
|
|
2616
|
+
timing(viewId, { opacity: 0 }, { duration: groupProps.duration ?? 300, easing: "easeIn" }).then(() => done()).catch(() => done());
|
|
2617
|
+
}
|
|
2618
|
+
expose({
|
|
2619
|
+
onEnter,
|
|
2620
|
+
onLeave,
|
|
2621
|
+
onMove
|
|
2622
|
+
});
|
|
2623
|
+
return () => {
|
|
2624
|
+
const children = slots.default?.() ?? [];
|
|
2625
|
+
return h31("TransitionGroup", {
|
|
2626
|
+
tag: groupProps.tag,
|
|
2627
|
+
name: groupProps.name,
|
|
2628
|
+
appear: groupProps.appear,
|
|
2629
|
+
persist: groupProps.persist,
|
|
2630
|
+
moveClass: groupProps.moveClass,
|
|
2631
|
+
onEnter,
|
|
2632
|
+
onLeave,
|
|
2633
|
+
onMove
|
|
2634
|
+
}, () => children);
|
|
2635
|
+
};
|
|
2636
|
+
}
|
|
2637
|
+
});
|
|
2638
|
+
|
|
2639
|
+
// src/components/KeepAlive.ts
|
|
2640
|
+
import {
|
|
2641
|
+
defineComponent as defineComponent32,
|
|
2642
|
+
onUnmounted as onUnmounted3,
|
|
2643
|
+
watch as watch6
|
|
2644
|
+
} from "@vue/runtime-core";
|
|
2645
|
+
function matches(pattern, name) {
|
|
2646
|
+
if (!pattern) return false;
|
|
2647
|
+
if (typeof pattern === "string") {
|
|
2648
|
+
return pattern === name;
|
|
2649
|
+
}
|
|
2650
|
+
if (pattern instanceof RegExp) {
|
|
2651
|
+
return pattern.test(name);
|
|
2652
|
+
}
|
|
2653
|
+
if (Array.isArray(pattern)) {
|
|
2654
|
+
return pattern.includes(name);
|
|
2655
|
+
}
|
|
2656
|
+
return false;
|
|
2657
|
+
}
|
|
2658
|
+
function getComponentName(vnode) {
|
|
2659
|
+
const component = vnode.type;
|
|
2660
|
+
if (typeof component === "object" && component !== null && "name" in component) {
|
|
2661
|
+
return component.name;
|
|
2662
|
+
}
|
|
2663
|
+
if (typeof component === "function") {
|
|
2664
|
+
return component.name;
|
|
2665
|
+
}
|
|
2666
|
+
return void 0;
|
|
2667
|
+
}
|
|
2668
|
+
var KeepAlive = defineComponent32({
|
|
2669
|
+
name: "KeepAlive",
|
|
2670
|
+
props: {
|
|
2671
|
+
include: [String, RegExp, Array],
|
|
2672
|
+
exclude: [String, RegExp, Array],
|
|
2673
|
+
max: [Number, String]
|
|
2674
|
+
},
|
|
2675
|
+
setup(props, { slots }) {
|
|
2676
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2677
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2678
|
+
const maxCacheSize = typeof props.max === "string" ? parseInt(props.max, 10) : props.max;
|
|
2679
|
+
function pruneCache(filter) {
|
|
2680
|
+
cache.forEach((_, key) => {
|
|
2681
|
+
if (!filter(key)) {
|
|
2682
|
+
cache.delete(key);
|
|
2683
|
+
keys.delete(key);
|
|
2684
|
+
}
|
|
2685
|
+
});
|
|
2686
|
+
}
|
|
2687
|
+
function pruneCacheEntry(key) {
|
|
2688
|
+
cache.delete(key);
|
|
2689
|
+
keys.delete(key);
|
|
2690
|
+
}
|
|
2691
|
+
watch6(
|
|
2692
|
+
() => [props.include, props.exclude],
|
|
2693
|
+
() => {
|
|
2694
|
+
if (!props.include && !props.exclude) return;
|
|
2695
|
+
pruneCache((name) => {
|
|
2696
|
+
if (props.include && !matches(props.include, name)) return false;
|
|
2697
|
+
if (props.exclude && matches(props.exclude, name)) return false;
|
|
2698
|
+
return true;
|
|
2699
|
+
});
|
|
2700
|
+
}
|
|
2701
|
+
);
|
|
2702
|
+
onUnmounted3(() => {
|
|
2703
|
+
cache.clear();
|
|
2704
|
+
keys.clear();
|
|
2705
|
+
});
|
|
2706
|
+
return () => {
|
|
2707
|
+
const children = slots.default?.() ?? [];
|
|
2708
|
+
if (!children.length) return children;
|
|
2709
|
+
const vnode = children[0];
|
|
2710
|
+
const name = getComponentName(vnode) ?? String(vnode.type);
|
|
2711
|
+
const key = name;
|
|
2712
|
+
if (props.include && !matches(props.include, name)) {
|
|
2713
|
+
return vnode;
|
|
2714
|
+
}
|
|
2715
|
+
if (props.exclude && matches(props.exclude, name)) {
|
|
2716
|
+
return vnode;
|
|
2717
|
+
}
|
|
2718
|
+
const cached = cache.get(key);
|
|
2719
|
+
if (cached) {
|
|
2720
|
+
keys.delete(key);
|
|
2721
|
+
keys.add(key);
|
|
2722
|
+
return cached.vnode;
|
|
2723
|
+
}
|
|
2724
|
+
if (maxCacheSize && cache.size >= maxCacheSize) {
|
|
2725
|
+
const firstKey = keys.values().next().value;
|
|
2726
|
+
if (firstKey) {
|
|
2727
|
+
pruneCacheEntry(firstKey);
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
cache.set(key, { vnode, key });
|
|
2731
|
+
keys.add(key);
|
|
2732
|
+
return vnode;
|
|
2733
|
+
};
|
|
2734
|
+
}
|
|
2735
|
+
});
|
|
2736
|
+
KeepAlive.isKeepAlive = true;
|
|
2737
|
+
|
|
2738
|
+
// src/components/VSuspense.ts
|
|
2739
|
+
import {
|
|
2740
|
+
defineComponent as defineComponent33,
|
|
2741
|
+
h as h32,
|
|
2742
|
+
ref as ref9,
|
|
2743
|
+
onMounted,
|
|
2744
|
+
shallowRef,
|
|
2745
|
+
watch as watch7,
|
|
2746
|
+
provide as provide2,
|
|
2747
|
+
inject as inject2
|
|
2748
|
+
} from "@vue/runtime-core";
|
|
2749
|
+
var suspenseContextKey = /* @__PURE__ */ Symbol("suspense");
|
|
2750
|
+
var VSuspense = defineComponent33({
|
|
2751
|
+
name: "Suspense",
|
|
2752
|
+
props: {
|
|
2753
|
+
timeout: { type: Number, default: 3e4 }
|
|
2754
|
+
},
|
|
2755
|
+
setup(_props, { slots }) {
|
|
2756
|
+
const hasError = ref9(false);
|
|
2757
|
+
const error = shallowRef(null);
|
|
2758
|
+
const pendingCount = ref9(0);
|
|
2759
|
+
const context = {
|
|
2760
|
+
hasError,
|
|
2761
|
+
error,
|
|
2762
|
+
pendingCount,
|
|
2763
|
+
resolve: () => {
|
|
2764
|
+
pendingCount.value--;
|
|
2765
|
+
},
|
|
2766
|
+
reject: (err) => {
|
|
2767
|
+
hasError.value = true;
|
|
2768
|
+
error.value = err;
|
|
2769
|
+
}
|
|
2770
|
+
};
|
|
2771
|
+
provide2(suspenseContextKey, context);
|
|
2772
|
+
return () => {
|
|
2773
|
+
if (hasError.value) {
|
|
2774
|
+
return slots.fallback?.({ error: error.value }) ?? null;
|
|
2775
|
+
}
|
|
2776
|
+
const defaultSlots = slots.default?.() ?? [];
|
|
2777
|
+
return defaultSlots;
|
|
2778
|
+
};
|
|
2779
|
+
}
|
|
2780
|
+
});
|
|
2781
|
+
|
|
2782
|
+
// src/components/index.ts
|
|
2783
|
+
var builtInComponents = {
|
|
2784
|
+
VView,
|
|
2785
|
+
VText,
|
|
2786
|
+
VButton,
|
|
2787
|
+
VInput,
|
|
2788
|
+
VSwitch,
|
|
2789
|
+
VActivityIndicator,
|
|
2790
|
+
VScrollView,
|
|
2791
|
+
VImage,
|
|
2792
|
+
VKeyboardAvoiding,
|
|
2793
|
+
VSafeArea,
|
|
2794
|
+
VSlider,
|
|
2795
|
+
VList,
|
|
2796
|
+
VModal,
|
|
2797
|
+
VAlertDialog,
|
|
2798
|
+
VStatusBar,
|
|
2799
|
+
VWebView,
|
|
2800
|
+
VProgressBar,
|
|
2801
|
+
VPicker,
|
|
2802
|
+
VSegmentedControl,
|
|
2803
|
+
VActionSheet,
|
|
2804
|
+
VRefreshControl,
|
|
2805
|
+
VPressable,
|
|
2806
|
+
VSectionList,
|
|
2807
|
+
VCheckbox,
|
|
2808
|
+
VRadio,
|
|
2809
|
+
VDropdown,
|
|
2810
|
+
VVideo,
|
|
2811
|
+
VFlatList,
|
|
2812
|
+
VTabBar,
|
|
2813
|
+
VDrawer,
|
|
2814
|
+
VDrawerItem,
|
|
2815
|
+
VDrawerSection,
|
|
2816
|
+
VTransition,
|
|
2817
|
+
VTransitionGroup,
|
|
2818
|
+
KeepAlive,
|
|
2819
|
+
VSuspense
|
|
2820
|
+
};
|
|
2821
|
+
|
|
2822
|
+
// src/errorBoundary.ts
|
|
2823
|
+
import { defineComponent as defineComponent34, ref as ref10, watch as watch8, onErrorCaptured } from "@vue/runtime-core";
|
|
2824
|
+
var ErrorBoundary = defineComponent34({
|
|
2825
|
+
name: "ErrorBoundary",
|
|
2826
|
+
props: {
|
|
2827
|
+
onError: Function,
|
|
2828
|
+
resetKeys: {
|
|
2829
|
+
type: Array,
|
|
2830
|
+
default: () => []
|
|
2831
|
+
}
|
|
2832
|
+
},
|
|
2833
|
+
setup(props, { slots }) {
|
|
2834
|
+
const error = ref10(null);
|
|
2835
|
+
const errorInfo = ref10("");
|
|
2836
|
+
onErrorCaptured((err, _instance, info) => {
|
|
2837
|
+
const normalizedError = err instanceof Error ? err : new Error(String(err));
|
|
2838
|
+
error.value = normalizedError;
|
|
2839
|
+
errorInfo.value = info;
|
|
2840
|
+
if (props.onError) {
|
|
2841
|
+
props.onError(normalizedError, info);
|
|
2842
|
+
}
|
|
2843
|
+
return false;
|
|
2844
|
+
});
|
|
2845
|
+
function reset() {
|
|
2846
|
+
error.value = null;
|
|
2847
|
+
errorInfo.value = "";
|
|
2848
|
+
}
|
|
2849
|
+
watch8(
|
|
2850
|
+
() => props.resetKeys,
|
|
2851
|
+
() => {
|
|
2852
|
+
if (error.value) {
|
|
2853
|
+
reset();
|
|
2854
|
+
}
|
|
2855
|
+
},
|
|
2856
|
+
{ deep: true }
|
|
2857
|
+
);
|
|
2858
|
+
return () => {
|
|
2859
|
+
if (error.value && slots.fallback) {
|
|
2860
|
+
return slots.fallback({ error: error.value, errorInfo: errorInfo.value, reset });
|
|
2861
|
+
}
|
|
2862
|
+
return slots.default?.();
|
|
2863
|
+
};
|
|
2864
|
+
}
|
|
2865
|
+
});
|
|
2866
|
+
|
|
2867
|
+
// src/index.ts
|
|
2868
|
+
export * from "@vue/runtime-core";
|
|
2869
|
+
|
|
2870
|
+
// src/stylesheet.ts
|
|
2871
|
+
var validStyleProperties = /* @__PURE__ */ new Set([
|
|
2872
|
+
// Layout (Yoga / Flexbox)
|
|
2873
|
+
"flex",
|
|
2874
|
+
"flexDirection",
|
|
2875
|
+
"flexWrap",
|
|
2876
|
+
"flexGrow",
|
|
2877
|
+
"flexShrink",
|
|
2878
|
+
"flexBasis",
|
|
2879
|
+
"justifyContent",
|
|
1772
2880
|
"alignItems",
|
|
1773
2881
|
"alignSelf",
|
|
1774
2882
|
"alignContent",
|
|
@@ -1874,11 +2982,78 @@ function createStyleSheet(styles) {
|
|
|
1874
2982
|
}
|
|
1875
2983
|
const result = {};
|
|
1876
2984
|
for (const key in styles) {
|
|
1877
|
-
|
|
2985
|
+
const styleKey = key;
|
|
2986
|
+
result[styleKey] = Object.freeze({ ...styles[styleKey] });
|
|
1878
2987
|
}
|
|
1879
2988
|
return Object.freeze(result);
|
|
1880
2989
|
}
|
|
1881
2990
|
|
|
2991
|
+
// src/directives/vShow.ts
|
|
2992
|
+
var vShow = {
|
|
2993
|
+
beforeMount(el, { value }) {
|
|
2994
|
+
try {
|
|
2995
|
+
NativeBridge.updateProp(el.id, "hidden", !value);
|
|
2996
|
+
} catch (err) {
|
|
2997
|
+
console.error("[VueNative] v-show beforeMount error:", err);
|
|
2998
|
+
}
|
|
2999
|
+
},
|
|
3000
|
+
updated(el, { value, oldValue }) {
|
|
3001
|
+
if (value === oldValue) return;
|
|
3002
|
+
try {
|
|
3003
|
+
NativeBridge.updateProp(el.id, "hidden", !value);
|
|
3004
|
+
} catch (err) {
|
|
3005
|
+
console.error("[VueNative] v-show updated error:", err);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
};
|
|
3009
|
+
|
|
3010
|
+
// src/directives/vModel.ts
|
|
3011
|
+
function getModelValue(event) {
|
|
3012
|
+
const modelEvent = event;
|
|
3013
|
+
return modelEvent?.value ?? modelEvent?.target?.value ?? event;
|
|
3014
|
+
}
|
|
3015
|
+
var vModel = {
|
|
3016
|
+
beforeMount(el, binding, vnode) {
|
|
3017
|
+
const { value, modifiers } = binding;
|
|
3018
|
+
const { lazy, number, trim } = modifiers || {};
|
|
3019
|
+
NativeBridge.updateProp(el.id, "value", value);
|
|
3020
|
+
const assign = vnode.dirs?.[0]?.value;
|
|
3021
|
+
if (typeof assign !== "function") {
|
|
3022
|
+
console.warn(
|
|
3023
|
+
"[VueNative] v-model directive requires the vnode to have an assign function. This usually happens when using v-model on native elements rendered by Vue, not custom components with modelValue props."
|
|
3024
|
+
);
|
|
3025
|
+
return;
|
|
3026
|
+
}
|
|
3027
|
+
const eventName = lazy ? "change" : "input";
|
|
3028
|
+
NativeBridge.addEventListener(el.id, eventName, (event) => {
|
|
3029
|
+
let newValue = getModelValue(event);
|
|
3030
|
+
if (trim && typeof newValue === "string") {
|
|
3031
|
+
newValue = newValue.trim();
|
|
3032
|
+
}
|
|
3033
|
+
if (number) {
|
|
3034
|
+
newValue = Number(newValue);
|
|
3035
|
+
}
|
|
3036
|
+
assign(newValue);
|
|
3037
|
+
});
|
|
3038
|
+
},
|
|
3039
|
+
updated(el, { value, oldValue, modifiers }, vnode) {
|
|
3040
|
+
if (value === oldValue) return;
|
|
3041
|
+
const _assign = vnode.dirs?.[0]?.value;
|
|
3042
|
+
let newValue = value;
|
|
3043
|
+
if (modifiers?.trim && typeof value === "string") {
|
|
3044
|
+
newValue = value.trim();
|
|
3045
|
+
}
|
|
3046
|
+
if (modifiers?.number) {
|
|
3047
|
+
newValue = Number(value);
|
|
3048
|
+
}
|
|
3049
|
+
NativeBridge.updateProp(el.id, "value", newValue);
|
|
3050
|
+
},
|
|
3051
|
+
beforeUnmount(el, _binding, _vnode) {
|
|
3052
|
+
NativeBridge.removeEventListener(el.id, "input");
|
|
3053
|
+
NativeBridge.removeEventListener(el.id, "change");
|
|
3054
|
+
}
|
|
3055
|
+
};
|
|
3056
|
+
|
|
1882
3057
|
// src/composables/useHaptics.ts
|
|
1883
3058
|
function useHaptics() {
|
|
1884
3059
|
function vibrate(style = "medium") {
|
|
@@ -1932,9 +3107,9 @@ function useAsyncStorage() {
|
|
|
1932
3107
|
}
|
|
1933
3108
|
|
|
1934
3109
|
// src/composables/useClipboard.ts
|
|
1935
|
-
import { ref as
|
|
3110
|
+
import { ref as ref11 } from "@vue/runtime-core";
|
|
1936
3111
|
function useClipboard() {
|
|
1937
|
-
const content =
|
|
3112
|
+
const content = ref11("");
|
|
1938
3113
|
function copy(text) {
|
|
1939
3114
|
return NativeBridge.invokeNativeModule("Clipboard", "copy", [text]).then(() => void 0);
|
|
1940
3115
|
}
|
|
@@ -1948,16 +3123,16 @@ function useClipboard() {
|
|
|
1948
3123
|
}
|
|
1949
3124
|
|
|
1950
3125
|
// src/composables/useDeviceInfo.ts
|
|
1951
|
-
import { ref as
|
|
3126
|
+
import { ref as ref12, onMounted as onMounted2 } from "@vue/runtime-core";
|
|
1952
3127
|
function useDeviceInfo() {
|
|
1953
|
-
const model =
|
|
1954
|
-
const systemVersion =
|
|
1955
|
-
const systemName =
|
|
1956
|
-
const name =
|
|
1957
|
-
const screenWidth =
|
|
1958
|
-
const screenHeight =
|
|
1959
|
-
const scale =
|
|
1960
|
-
const isLoaded =
|
|
3128
|
+
const model = ref12("");
|
|
3129
|
+
const systemVersion = ref12("");
|
|
3130
|
+
const systemName = ref12("");
|
|
3131
|
+
const name = ref12("");
|
|
3132
|
+
const screenWidth = ref12(0);
|
|
3133
|
+
const screenHeight = ref12(0);
|
|
3134
|
+
const scale = ref12(1);
|
|
3135
|
+
const isLoaded = ref12(false);
|
|
1961
3136
|
async function fetchInfo() {
|
|
1962
3137
|
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
|
|
1963
3138
|
model.value = info.model ?? "";
|
|
@@ -1969,7 +3144,7 @@ function useDeviceInfo() {
|
|
|
1969
3144
|
scale.value = info.scale ?? 1;
|
|
1970
3145
|
isLoaded.value = true;
|
|
1971
3146
|
}
|
|
1972
|
-
|
|
3147
|
+
onMounted2(() => {
|
|
1973
3148
|
fetchInfo();
|
|
1974
3149
|
});
|
|
1975
3150
|
return {
|
|
@@ -1986,10 +3161,10 @@ function useDeviceInfo() {
|
|
|
1986
3161
|
}
|
|
1987
3162
|
|
|
1988
3163
|
// src/composables/useKeyboard.ts
|
|
1989
|
-
import { ref as
|
|
3164
|
+
import { ref as ref13 } from "@vue/runtime-core";
|
|
1990
3165
|
function useKeyboard() {
|
|
1991
|
-
const isVisible =
|
|
1992
|
-
const height =
|
|
3166
|
+
const isVisible = ref13(false);
|
|
3167
|
+
const height = ref13(0);
|
|
1993
3168
|
function dismiss() {
|
|
1994
3169
|
return NativeBridge.invokeNativeModule("Keyboard", "dismiss", []).then(() => void 0);
|
|
1995
3170
|
}
|
|
@@ -2002,61 +3177,11 @@ function useKeyboard() {
|
|
|
2002
3177
|
return { isVisible, height, dismiss, getHeight };
|
|
2003
3178
|
}
|
|
2004
3179
|
|
|
2005
|
-
// src/composables/useAnimation.ts
|
|
2006
|
-
var Easing = {
|
|
2007
|
-
linear: "linear",
|
|
2008
|
-
ease: "ease",
|
|
2009
|
-
easeIn: "easeIn",
|
|
2010
|
-
easeOut: "easeOut",
|
|
2011
|
-
easeInOut: "easeInOut"
|
|
2012
|
-
};
|
|
2013
|
-
function useAnimation() {
|
|
2014
|
-
function timing(viewId, toStyles, config = {}) {
|
|
2015
|
-
return NativeBridge.invokeNativeModule("Animation", "timing", [viewId, toStyles, config]);
|
|
2016
|
-
}
|
|
2017
|
-
function spring(viewId, toStyles, config = {}) {
|
|
2018
|
-
return NativeBridge.invokeNativeModule("Animation", "spring", [viewId, toStyles, config]);
|
|
2019
|
-
}
|
|
2020
|
-
function keyframe(viewId, steps, config = {}) {
|
|
2021
|
-
return NativeBridge.invokeNativeModule("Animation", "keyframe", [viewId, steps, config]);
|
|
2022
|
-
}
|
|
2023
|
-
function sequence(animations) {
|
|
2024
|
-
return NativeBridge.invokeNativeModule("Animation", "sequence", [animations]);
|
|
2025
|
-
}
|
|
2026
|
-
function parallel(animations) {
|
|
2027
|
-
return NativeBridge.invokeNativeModule("Animation", "parallel", [animations]);
|
|
2028
|
-
}
|
|
2029
|
-
function fadeOut(viewId, duration = 300) {
|
|
2030
|
-
return timing(viewId, { opacity: 0 }, { duration });
|
|
2031
|
-
}
|
|
2032
|
-
function fadeIn(viewId, duration = 300) {
|
|
2033
|
-
return timing(viewId, { opacity: 1 }, { duration });
|
|
2034
|
-
}
|
|
2035
|
-
function slideInFromRight(viewId, duration = 300) {
|
|
2036
|
-
return timing(viewId, { translateX: 0 }, { duration, easing: "easeOut" });
|
|
2037
|
-
}
|
|
2038
|
-
function slideOutToRight(viewId, duration = 300) {
|
|
2039
|
-
return timing(viewId, { translateX: 400 }, { duration, easing: "easeIn" });
|
|
2040
|
-
}
|
|
2041
|
-
return {
|
|
2042
|
-
timing,
|
|
2043
|
-
spring,
|
|
2044
|
-
keyframe,
|
|
2045
|
-
sequence,
|
|
2046
|
-
parallel,
|
|
2047
|
-
fadeIn,
|
|
2048
|
-
fadeOut,
|
|
2049
|
-
slideInFromRight,
|
|
2050
|
-
slideOutToRight,
|
|
2051
|
-
Easing
|
|
2052
|
-
};
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
3180
|
// src/composables/useNetwork.ts
|
|
2056
|
-
import { ref as
|
|
3181
|
+
import { ref as ref14, onUnmounted as onUnmounted4 } from "@vue/runtime-core";
|
|
2057
3182
|
function useNetwork() {
|
|
2058
|
-
const isConnected =
|
|
2059
|
-
const connectionType =
|
|
3183
|
+
const isConnected = ref14(true);
|
|
3184
|
+
const connectionType = ref14("unknown");
|
|
2060
3185
|
let lastEventTime = 0;
|
|
2061
3186
|
const unsubscribe = NativeBridge.onGlobalEvent("network:change", (payload) => {
|
|
2062
3187
|
lastEventTime = Date.now();
|
|
@@ -2071,14 +3196,14 @@ function useNetwork() {
|
|
|
2071
3196
|
}
|
|
2072
3197
|
}).catch(() => {
|
|
2073
3198
|
});
|
|
2074
|
-
|
|
3199
|
+
onUnmounted4(unsubscribe);
|
|
2075
3200
|
return { isConnected, connectionType };
|
|
2076
3201
|
}
|
|
2077
3202
|
|
|
2078
3203
|
// src/composables/useAppState.ts
|
|
2079
|
-
import { ref as
|
|
3204
|
+
import { ref as ref15, onUnmounted as onUnmounted5 } from "@vue/runtime-core";
|
|
2080
3205
|
function useAppState() {
|
|
2081
|
-
const state =
|
|
3206
|
+
const state = ref15("active");
|
|
2082
3207
|
NativeBridge.invokeNativeModule("AppState", "getState").then((s) => {
|
|
2083
3208
|
state.value = s;
|
|
2084
3209
|
}).catch(() => {
|
|
@@ -2086,7 +3211,7 @@ function useAppState() {
|
|
|
2086
3211
|
const unsubscribe = NativeBridge.onGlobalEvent("appState:change", (payload) => {
|
|
2087
3212
|
state.value = payload.state;
|
|
2088
3213
|
});
|
|
2089
|
-
|
|
3214
|
+
onUnmounted5(unsubscribe);
|
|
2090
3215
|
return { state };
|
|
2091
3216
|
}
|
|
2092
3217
|
|
|
@@ -2121,10 +3246,10 @@ function usePermissions() {
|
|
|
2121
3246
|
}
|
|
2122
3247
|
|
|
2123
3248
|
// src/composables/useGeolocation.ts
|
|
2124
|
-
import { ref as
|
|
3249
|
+
import { ref as ref16, onUnmounted as onUnmounted6 } from "@vue/runtime-core";
|
|
2125
3250
|
function useGeolocation() {
|
|
2126
|
-
const coords =
|
|
2127
|
-
const error =
|
|
3251
|
+
const coords = ref16(null);
|
|
3252
|
+
const error = ref16(null);
|
|
2128
3253
|
let watchId = null;
|
|
2129
3254
|
async function getCurrentPosition() {
|
|
2130
3255
|
try {
|
|
@@ -2149,7 +3274,7 @@ function useGeolocation() {
|
|
|
2149
3274
|
const unsubscribeError = NativeBridge.onGlobalEvent("location:error", (payload) => {
|
|
2150
3275
|
error.value = payload.message;
|
|
2151
3276
|
});
|
|
2152
|
-
|
|
3277
|
+
onUnmounted6(() => {
|
|
2153
3278
|
unsubscribe();
|
|
2154
3279
|
unsubscribeError();
|
|
2155
3280
|
if (watchId !== null) clearWatch(watchId);
|
|
@@ -2169,7 +3294,7 @@ function useGeolocation() {
|
|
|
2169
3294
|
}
|
|
2170
3295
|
|
|
2171
3296
|
// src/composables/useCamera.ts
|
|
2172
|
-
import { onUnmounted as
|
|
3297
|
+
import { onUnmounted as onUnmounted7 } from "@vue/runtime-core";
|
|
2173
3298
|
function useCamera() {
|
|
2174
3299
|
const qrCleanups = [];
|
|
2175
3300
|
async function launchCamera(options = {}) {
|
|
@@ -2192,7 +3317,7 @@ function useCamera() {
|
|
|
2192
3317
|
qrCleanups.push(unsubscribe);
|
|
2193
3318
|
return unsubscribe;
|
|
2194
3319
|
}
|
|
2195
|
-
|
|
3320
|
+
onUnmounted7(() => {
|
|
2196
3321
|
NativeBridge.invokeNativeModule("Camera", "stopQRScan").catch(() => {
|
|
2197
3322
|
});
|
|
2198
3323
|
qrCleanups.forEach((fn) => fn());
|
|
@@ -2202,10 +3327,10 @@ function useCamera() {
|
|
|
2202
3327
|
}
|
|
2203
3328
|
|
|
2204
3329
|
// src/composables/useNotifications.ts
|
|
2205
|
-
import { ref as
|
|
3330
|
+
import { ref as ref17, onUnmounted as onUnmounted8 } from "@vue/runtime-core";
|
|
2206
3331
|
function useNotifications() {
|
|
2207
|
-
const isGranted =
|
|
2208
|
-
const pushToken =
|
|
3332
|
+
const isGranted = ref17(false);
|
|
3333
|
+
const pushToken = ref17(null);
|
|
2209
3334
|
async function requestPermission() {
|
|
2210
3335
|
const granted = await NativeBridge.invokeNativeModule("Notifications", "requestPermission");
|
|
2211
3336
|
isGranted.value = granted;
|
|
@@ -2225,7 +3350,7 @@ function useNotifications() {
|
|
|
2225
3350
|
}
|
|
2226
3351
|
function onNotification(handler) {
|
|
2227
3352
|
const unsubscribe = NativeBridge.onGlobalEvent("notification:received", handler);
|
|
2228
|
-
|
|
3353
|
+
onUnmounted8(unsubscribe);
|
|
2229
3354
|
return unsubscribe;
|
|
2230
3355
|
}
|
|
2231
3356
|
async function registerForPush() {
|
|
@@ -2239,12 +3364,12 @@ function useNotifications() {
|
|
|
2239
3364
|
pushToken.value = payload.token;
|
|
2240
3365
|
handler(payload.token);
|
|
2241
3366
|
});
|
|
2242
|
-
|
|
3367
|
+
onUnmounted8(unsubscribe);
|
|
2243
3368
|
return unsubscribe;
|
|
2244
3369
|
}
|
|
2245
3370
|
function onPushReceived(handler) {
|
|
2246
3371
|
const unsubscribe = NativeBridge.onGlobalEvent("push:received", handler);
|
|
2247
|
-
|
|
3372
|
+
onUnmounted8(unsubscribe);
|
|
2248
3373
|
return unsubscribe;
|
|
2249
3374
|
}
|
|
2250
3375
|
return {
|
|
@@ -2280,7 +3405,10 @@ function useBiometry() {
|
|
|
2280
3405
|
}
|
|
2281
3406
|
|
|
2282
3407
|
// src/composables/useHttp.ts
|
|
2283
|
-
import { ref as
|
|
3408
|
+
import { ref as ref18, onUnmounted as onUnmounted9 } from "@vue/runtime-core";
|
|
3409
|
+
function isQueryRequestOptions(value) {
|
|
3410
|
+
return "params" in value || "headers" in value;
|
|
3411
|
+
}
|
|
2284
3412
|
function useHttp(config = {}) {
|
|
2285
3413
|
if (config.pins && Object.keys(config.pins).length > 0) {
|
|
2286
3414
|
const configurePins = globalThis.__VN_configurePins;
|
|
@@ -2290,39 +3418,70 @@ function useHttp(config = {}) {
|
|
|
2290
3418
|
NativeBridge.invokeNativeModule("Http", "configurePins", [config.pins]);
|
|
2291
3419
|
}
|
|
2292
3420
|
}
|
|
2293
|
-
const loading =
|
|
2294
|
-
const error =
|
|
3421
|
+
const loading = ref18(false);
|
|
3422
|
+
const error = ref18(null);
|
|
2295
3423
|
let isMounted = true;
|
|
2296
|
-
|
|
3424
|
+
onUnmounted9(() => {
|
|
2297
3425
|
isMounted = false;
|
|
2298
3426
|
});
|
|
3427
|
+
const BODY_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
|
|
3428
|
+
function parseResponseHeaders(response) {
|
|
3429
|
+
const result = {};
|
|
3430
|
+
if (!response.headers) return result;
|
|
3431
|
+
try {
|
|
3432
|
+
if (typeof response.headers.forEach === "function") {
|
|
3433
|
+
response.headers.forEach((value, key) => {
|
|
3434
|
+
result[key] = value;
|
|
3435
|
+
});
|
|
3436
|
+
} else if (typeof response.headers.entries === "function") {
|
|
3437
|
+
for (const [key, value] of response.headers.entries()) {
|
|
3438
|
+
result[key] = value;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
} catch {
|
|
3442
|
+
}
|
|
3443
|
+
return result;
|
|
3444
|
+
}
|
|
2299
3445
|
async function request(method, url, options = {}) {
|
|
2300
3446
|
const fullUrl = config.baseURL ? `${config.baseURL}${url}` : url;
|
|
2301
3447
|
loading.value = true;
|
|
2302
3448
|
error.value = null;
|
|
3449
|
+
let controller;
|
|
3450
|
+
let timeoutId;
|
|
3451
|
+
if (config.timeout && config.timeout > 0 && typeof AbortController !== "undefined") {
|
|
3452
|
+
controller = new AbortController();
|
|
3453
|
+
timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
3454
|
+
}
|
|
2303
3455
|
try {
|
|
3456
|
+
const upperMethod = method.toUpperCase();
|
|
2304
3457
|
const mergedHeaders = {
|
|
2305
|
-
"Content-Type": "application/json",
|
|
2306
3458
|
...config.headers ?? {},
|
|
2307
3459
|
...options.headers ?? {}
|
|
2308
3460
|
};
|
|
3461
|
+
if (BODY_METHODS.has(upperMethod) && !mergedHeaders["Content-Type"]) {
|
|
3462
|
+
mergedHeaders["Content-Type"] = "application/json";
|
|
3463
|
+
}
|
|
2309
3464
|
const fetchOptions = {
|
|
2310
|
-
method:
|
|
3465
|
+
method: upperMethod,
|
|
2311
3466
|
headers: mergedHeaders
|
|
2312
3467
|
};
|
|
3468
|
+
if (controller) {
|
|
3469
|
+
fetchOptions.signal = controller.signal;
|
|
3470
|
+
}
|
|
2313
3471
|
if (options.body !== void 0) {
|
|
2314
3472
|
fetchOptions.body = JSON.stringify(options.body);
|
|
2315
3473
|
}
|
|
2316
3474
|
const response = await fetch(fullUrl, fetchOptions);
|
|
2317
3475
|
const data = await response.json();
|
|
3476
|
+
const responseHeaders = parseResponseHeaders(response);
|
|
2318
3477
|
if (!isMounted) {
|
|
2319
|
-
return { data, status: response.status, ok: response.ok, headers:
|
|
3478
|
+
return { data, status: response.status, ok: response.ok, headers: responseHeaders };
|
|
2320
3479
|
}
|
|
2321
3480
|
return {
|
|
2322
3481
|
data,
|
|
2323
3482
|
status: response.status,
|
|
2324
3483
|
ok: response.ok,
|
|
2325
|
-
headers:
|
|
3484
|
+
headers: responseHeaders
|
|
2326
3485
|
};
|
|
2327
3486
|
} catch (e) {
|
|
2328
3487
|
const msg = e instanceof Error ? e.message : String(e);
|
|
@@ -2331,6 +3490,9 @@ function useHttp(config = {}) {
|
|
|
2331
3490
|
}
|
|
2332
3491
|
throw e;
|
|
2333
3492
|
} finally {
|
|
3493
|
+
if (timeoutId !== void 0) {
|
|
3494
|
+
clearTimeout(timeoutId);
|
|
3495
|
+
}
|
|
2334
3496
|
if (isMounted) {
|
|
2335
3497
|
loading.value = false;
|
|
2336
3498
|
}
|
|
@@ -2345,30 +3507,24 @@ function useHttp(config = {}) {
|
|
|
2345
3507
|
loading,
|
|
2346
3508
|
error,
|
|
2347
3509
|
get: (url, options) => {
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
}
|
|
2351
|
-
const opts = options;
|
|
2352
|
-
return request("GET", buildUrl(url, opts?.params), { headers: opts?.headers });
|
|
3510
|
+
const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
|
|
3511
|
+
return request("GET", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
|
|
2353
3512
|
},
|
|
2354
3513
|
post: (url, body, headers) => request("POST", url, { body, headers }),
|
|
2355
3514
|
put: (url, body, headers) => request("PUT", url, { body, headers }),
|
|
2356
3515
|
patch: (url, body, headers) => request("PATCH", url, { body, headers }),
|
|
2357
3516
|
delete: (url, options) => {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
}
|
|
2361
|
-
const opts = options;
|
|
2362
|
-
return request("DELETE", buildUrl(url, opts?.params), { headers: opts?.headers });
|
|
3517
|
+
const normalizedOptions = options ? isQueryRequestOptions(options) ? options : { headers: options } : void 0;
|
|
3518
|
+
return request("DELETE", buildUrl(url, normalizedOptions?.params), { headers: normalizedOptions?.headers });
|
|
2363
3519
|
}
|
|
2364
3520
|
};
|
|
2365
3521
|
}
|
|
2366
3522
|
|
|
2367
3523
|
// src/composables/useColorScheme.ts
|
|
2368
|
-
import { ref as
|
|
3524
|
+
import { ref as ref19, onUnmounted as onUnmounted10 } from "@vue/runtime-core";
|
|
2369
3525
|
function useColorScheme() {
|
|
2370
|
-
const colorScheme =
|
|
2371
|
-
const isDark =
|
|
3526
|
+
const colorScheme = ref19("light");
|
|
3527
|
+
const isDark = ref19(false);
|
|
2372
3528
|
const unsubscribe = NativeBridge.onGlobalEvent(
|
|
2373
3529
|
"colorScheme:change",
|
|
2374
3530
|
(payload) => {
|
|
@@ -2376,15 +3532,15 @@ function useColorScheme() {
|
|
|
2376
3532
|
isDark.value = payload.colorScheme === "dark";
|
|
2377
3533
|
}
|
|
2378
3534
|
);
|
|
2379
|
-
|
|
3535
|
+
onUnmounted10(unsubscribe);
|
|
2380
3536
|
return { colorScheme, isDark };
|
|
2381
3537
|
}
|
|
2382
3538
|
|
|
2383
3539
|
// src/composables/useBackHandler.ts
|
|
2384
|
-
import { onMounted as
|
|
3540
|
+
import { onMounted as onMounted3, onUnmounted as onUnmounted11 } from "@vue/runtime-core";
|
|
2385
3541
|
function useBackHandler(handler) {
|
|
2386
3542
|
let unsubscribe = null;
|
|
2387
|
-
|
|
3543
|
+
onMounted3(() => {
|
|
2388
3544
|
unsubscribe = NativeBridge.onGlobalEvent("hardware:backPress", () => {
|
|
2389
3545
|
const handled = handler();
|
|
2390
3546
|
if (!handled) {
|
|
@@ -2393,7 +3549,7 @@ function useBackHandler(handler) {
|
|
|
2393
3549
|
}
|
|
2394
3550
|
});
|
|
2395
3551
|
});
|
|
2396
|
-
|
|
3552
|
+
onUnmounted11(() => {
|
|
2397
3553
|
unsubscribe?.();
|
|
2398
3554
|
unsubscribe = null;
|
|
2399
3555
|
});
|
|
@@ -2417,11 +3573,11 @@ function useSecureStorage() {
|
|
|
2417
3573
|
}
|
|
2418
3574
|
|
|
2419
3575
|
// src/composables/useI18n.ts
|
|
2420
|
-
import { ref as
|
|
3576
|
+
import { ref as ref20, onMounted as onMounted4 } from "@vue/runtime-core";
|
|
2421
3577
|
function useI18n() {
|
|
2422
|
-
const isRTL =
|
|
2423
|
-
const locale =
|
|
2424
|
-
|
|
3578
|
+
const isRTL = ref20(false);
|
|
3579
|
+
const locale = ref20("en");
|
|
3580
|
+
onMounted4(async () => {
|
|
2425
3581
|
try {
|
|
2426
3582
|
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getDeviceInfo", []);
|
|
2427
3583
|
locale.value = info?.locale || "en";
|
|
@@ -2432,21 +3588,13 @@ function useI18n() {
|
|
|
2432
3588
|
return { isRTL, locale };
|
|
2433
3589
|
}
|
|
2434
3590
|
|
|
2435
|
-
// src/composables/usePlatform.ts
|
|
2436
|
-
function usePlatform() {
|
|
2437
|
-
const platform = typeof __PLATFORM__ !== "undefined" ? __PLATFORM__ : "ios";
|
|
2438
|
-
const isIOS = platform === "ios";
|
|
2439
|
-
const isAndroid = platform === "android";
|
|
2440
|
-
return { platform, isIOS, isAndroid };
|
|
2441
|
-
}
|
|
2442
|
-
|
|
2443
3591
|
// src/composables/useDimensions.ts
|
|
2444
|
-
import { ref as
|
|
3592
|
+
import { ref as ref21, onMounted as onMounted5, onUnmounted as onUnmounted12 } from "@vue/runtime-core";
|
|
2445
3593
|
function useDimensions() {
|
|
2446
|
-
const width =
|
|
2447
|
-
const height =
|
|
2448
|
-
const scale =
|
|
2449
|
-
|
|
3594
|
+
const width = ref21(0);
|
|
3595
|
+
const height = ref21(0);
|
|
3596
|
+
const scale = ref21(1);
|
|
3597
|
+
onMounted5(async () => {
|
|
2450
3598
|
try {
|
|
2451
3599
|
const info = await NativeBridge.invokeNativeModule("DeviceInfo", "getInfo", []);
|
|
2452
3600
|
width.value = info?.screenWidth || 0;
|
|
@@ -2460,12 +3608,12 @@ function useDimensions() {
|
|
|
2460
3608
|
if (payload.height != null) height.value = payload.height;
|
|
2461
3609
|
if (payload.scale != null) scale.value = payload.scale;
|
|
2462
3610
|
});
|
|
2463
|
-
|
|
3611
|
+
onUnmounted12(cleanup);
|
|
2464
3612
|
return { width, height, scale };
|
|
2465
3613
|
}
|
|
2466
3614
|
|
|
2467
3615
|
// src/composables/useWebSocket.ts
|
|
2468
|
-
import { ref as
|
|
3616
|
+
import { ref as ref22, onUnmounted as onUnmounted13 } from "@vue/runtime-core";
|
|
2469
3617
|
var connectionCounter = 0;
|
|
2470
3618
|
function useWebSocket(url, options = {}) {
|
|
2471
3619
|
const {
|
|
@@ -2475,9 +3623,9 @@ function useWebSocket(url, options = {}) {
|
|
|
2475
3623
|
reconnectInterval = 1e3
|
|
2476
3624
|
} = options;
|
|
2477
3625
|
const connectionId = `ws_${++connectionCounter}_${Date.now()}`;
|
|
2478
|
-
const status =
|
|
2479
|
-
const lastMessage =
|
|
2480
|
-
const error =
|
|
3626
|
+
const status = ref22("CLOSED");
|
|
3627
|
+
const lastMessage = ref22(null);
|
|
3628
|
+
const error = ref22(null);
|
|
2481
3629
|
let reconnectAttempts = 0;
|
|
2482
3630
|
let reconnectTimer = null;
|
|
2483
3631
|
const MAX_PENDING_MESSAGES = 100;
|
|
@@ -2562,7 +3710,7 @@ function useWebSocket(url, options = {}) {
|
|
|
2562
3710
|
if (autoConnect) {
|
|
2563
3711
|
open();
|
|
2564
3712
|
}
|
|
2565
|
-
|
|
3713
|
+
onUnmounted13(() => {
|
|
2566
3714
|
if (reconnectTimer) {
|
|
2567
3715
|
clearTimeout(reconnectTimer);
|
|
2568
3716
|
}
|
|
@@ -2631,12 +3779,12 @@ function useFileSystem() {
|
|
|
2631
3779
|
}
|
|
2632
3780
|
|
|
2633
3781
|
// src/composables/useSensors.ts
|
|
2634
|
-
import { ref as
|
|
3782
|
+
import { ref as ref23, onUnmounted as onUnmounted14 } from "@vue/runtime-core";
|
|
2635
3783
|
function useAccelerometer(options = {}) {
|
|
2636
|
-
const x =
|
|
2637
|
-
const y =
|
|
2638
|
-
const z =
|
|
2639
|
-
const isAvailable =
|
|
3784
|
+
const x = ref23(0);
|
|
3785
|
+
const y = ref23(0);
|
|
3786
|
+
const z = ref23(0);
|
|
3787
|
+
const isAvailable = ref23(false);
|
|
2640
3788
|
let running = false;
|
|
2641
3789
|
let unsubscribe = null;
|
|
2642
3790
|
NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["accelerometer"]).then((result) => {
|
|
@@ -2664,16 +3812,16 @@ function useAccelerometer(options = {}) {
|
|
|
2664
3812
|
NativeBridge.invokeNativeModule("Sensors", "stopAccelerometer").catch(() => {
|
|
2665
3813
|
});
|
|
2666
3814
|
}
|
|
2667
|
-
|
|
3815
|
+
onUnmounted14(() => {
|
|
2668
3816
|
stop();
|
|
2669
3817
|
});
|
|
2670
3818
|
return { x, y, z, isAvailable, start, stop };
|
|
2671
3819
|
}
|
|
2672
3820
|
function useGyroscope(options = {}) {
|
|
2673
|
-
const x =
|
|
2674
|
-
const y =
|
|
2675
|
-
const z =
|
|
2676
|
-
const isAvailable =
|
|
3821
|
+
const x = ref23(0);
|
|
3822
|
+
const y = ref23(0);
|
|
3823
|
+
const z = ref23(0);
|
|
3824
|
+
const isAvailable = ref23(false);
|
|
2677
3825
|
let running = false;
|
|
2678
3826
|
let unsubscribe = null;
|
|
2679
3827
|
NativeBridge.invokeNativeModule("Sensors", "isAvailable", ["gyroscope"]).then((result) => {
|
|
@@ -2701,20 +3849,31 @@ function useGyroscope(options = {}) {
|
|
|
2701
3849
|
NativeBridge.invokeNativeModule("Sensors", "stopGyroscope").catch(() => {
|
|
2702
3850
|
});
|
|
2703
3851
|
}
|
|
2704
|
-
|
|
3852
|
+
onUnmounted14(() => {
|
|
2705
3853
|
stop();
|
|
2706
3854
|
});
|
|
2707
3855
|
return { x, y, z, isAvailable, start, stop };
|
|
2708
3856
|
}
|
|
2709
3857
|
|
|
2710
3858
|
// src/composables/useAudio.ts
|
|
2711
|
-
import { ref as
|
|
3859
|
+
import { ref as ref24, onUnmounted as onUnmounted15 } from "@vue/runtime-core";
|
|
3860
|
+
function asRecord(value) {
|
|
3861
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
3862
|
+
}
|
|
3863
|
+
function getNumberProp(record, key) {
|
|
3864
|
+
const value = record?.[key];
|
|
3865
|
+
return typeof value === "number" ? value : void 0;
|
|
3866
|
+
}
|
|
3867
|
+
function getStringProp(record, key) {
|
|
3868
|
+
const value = record?.[key];
|
|
3869
|
+
return typeof value === "string" ? value : void 0;
|
|
3870
|
+
}
|
|
2712
3871
|
function useAudio() {
|
|
2713
|
-
const duration =
|
|
2714
|
-
const position =
|
|
2715
|
-
const isPlaying =
|
|
2716
|
-
const isRecording =
|
|
2717
|
-
const error =
|
|
3872
|
+
const duration = ref24(0);
|
|
3873
|
+
const position = ref24(0);
|
|
3874
|
+
const isPlaying = ref24(false);
|
|
3875
|
+
const isRecording = ref24(false);
|
|
3876
|
+
const error = ref24(null);
|
|
2718
3877
|
const unsubProgress = NativeBridge.onGlobalEvent("audio:progress", (payload) => {
|
|
2719
3878
|
position.value = payload.currentTime ?? 0;
|
|
2720
3879
|
duration.value = payload.duration ?? 0;
|
|
@@ -2727,7 +3886,7 @@ function useAudio() {
|
|
|
2727
3886
|
error.value = payload.message ?? "Unknown audio error";
|
|
2728
3887
|
isPlaying.value = false;
|
|
2729
3888
|
});
|
|
2730
|
-
|
|
3889
|
+
onUnmounted15(() => {
|
|
2731
3890
|
unsubProgress();
|
|
2732
3891
|
unsubComplete();
|
|
2733
3892
|
unsubError();
|
|
@@ -2740,9 +3899,10 @@ function useAudio() {
|
|
|
2740
3899
|
});
|
|
2741
3900
|
async function play(uri, options = {}) {
|
|
2742
3901
|
error.value = null;
|
|
2743
|
-
const result = await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]);
|
|
2744
|
-
|
|
2745
|
-
|
|
3902
|
+
const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "play", [uri, options]));
|
|
3903
|
+
const audioDuration = getNumberProp(result, "duration");
|
|
3904
|
+
if (audioDuration !== void 0) {
|
|
3905
|
+
duration.value = audioDuration;
|
|
2746
3906
|
}
|
|
2747
3907
|
isPlaying.value = true;
|
|
2748
3908
|
}
|
|
@@ -2768,14 +3928,17 @@ function useAudio() {
|
|
|
2768
3928
|
}
|
|
2769
3929
|
async function startRecording(options = {}) {
|
|
2770
3930
|
error.value = null;
|
|
2771
|
-
const result = await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]);
|
|
3931
|
+
const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "startRecording", [options]));
|
|
2772
3932
|
isRecording.value = true;
|
|
2773
|
-
return result
|
|
3933
|
+
return getStringProp(result, "uri") ?? "";
|
|
2774
3934
|
}
|
|
2775
3935
|
async function stopRecording() {
|
|
2776
|
-
const result = await NativeBridge.invokeNativeModule("Audio", "stopRecording", []);
|
|
3936
|
+
const result = asRecord(await NativeBridge.invokeNativeModule("Audio", "stopRecording", []));
|
|
2777
3937
|
isRecording.value = false;
|
|
2778
|
-
return {
|
|
3938
|
+
return {
|
|
3939
|
+
uri: getStringProp(result, "uri") ?? "",
|
|
3940
|
+
duration: getNumberProp(result, "duration") ?? 0
|
|
3941
|
+
};
|
|
2779
3942
|
}
|
|
2780
3943
|
async function pauseRecording() {
|
|
2781
3944
|
await NativeBridge.invokeNativeModule("Audio", "pauseRecording", []);
|
|
@@ -2806,9 +3969,9 @@ function useAudio() {
|
|
|
2806
3969
|
}
|
|
2807
3970
|
|
|
2808
3971
|
// src/composables/useDatabase.ts
|
|
2809
|
-
import { ref as
|
|
3972
|
+
import { ref as ref25, onUnmounted as onUnmounted16 } from "@vue/runtime-core";
|
|
2810
3973
|
function useDatabase(name = "default") {
|
|
2811
|
-
const isOpen =
|
|
3974
|
+
const isOpen = ref25(false);
|
|
2812
3975
|
let opened = false;
|
|
2813
3976
|
async function ensureOpen() {
|
|
2814
3977
|
if (opened) return;
|
|
@@ -2850,7 +4013,7 @@ function useDatabase(name = "default") {
|
|
|
2850
4013
|
opened = false;
|
|
2851
4014
|
isOpen.value = false;
|
|
2852
4015
|
}
|
|
2853
|
-
|
|
4016
|
+
onUnmounted16(() => {
|
|
2854
4017
|
if (opened) {
|
|
2855
4018
|
NativeBridge.invokeNativeModule("Database", "close", [name]).catch(() => {
|
|
2856
4019
|
});
|
|
@@ -2862,12 +4025,12 @@ function useDatabase(name = "default") {
|
|
|
2862
4025
|
}
|
|
2863
4026
|
|
|
2864
4027
|
// src/composables/usePerformance.ts
|
|
2865
|
-
import { ref as
|
|
4028
|
+
import { ref as ref26, onUnmounted as onUnmounted17 } from "@vue/runtime-core";
|
|
2866
4029
|
function usePerformance() {
|
|
2867
|
-
const isProfiling =
|
|
2868
|
-
const fps =
|
|
2869
|
-
const memoryMB =
|
|
2870
|
-
const bridgeOps =
|
|
4030
|
+
const isProfiling = ref26(false);
|
|
4031
|
+
const fps = ref26(0);
|
|
4032
|
+
const memoryMB = ref26(0);
|
|
4033
|
+
const bridgeOps = ref26(0);
|
|
2871
4034
|
let unsubscribe = null;
|
|
2872
4035
|
function handleMetrics(payload) {
|
|
2873
4036
|
fps.value = payload.fps ?? 0;
|
|
@@ -2892,7 +4055,7 @@ function usePerformance() {
|
|
|
2892
4055
|
async function getMetrics() {
|
|
2893
4056
|
return NativeBridge.invokeNativeModule("Performance", "getMetrics", []);
|
|
2894
4057
|
}
|
|
2895
|
-
|
|
4058
|
+
onUnmounted17(() => {
|
|
2896
4059
|
if (isProfiling.value) {
|
|
2897
4060
|
NativeBridge.invokeNativeModule("Performance", "stopProfiling", []).catch(() => {
|
|
2898
4061
|
});
|
|
@@ -2915,10 +4078,10 @@ function usePerformance() {
|
|
|
2915
4078
|
}
|
|
2916
4079
|
|
|
2917
4080
|
// src/composables/useSharedElementTransition.ts
|
|
2918
|
-
import { ref as
|
|
4081
|
+
import { ref as ref27, onUnmounted as onUnmounted18 } from "@vue/runtime-core";
|
|
2919
4082
|
var sharedElementRegistry = /* @__PURE__ */ new Map();
|
|
2920
4083
|
function useSharedElementTransition(elementId) {
|
|
2921
|
-
const viewId =
|
|
4084
|
+
const viewId = ref27(null);
|
|
2922
4085
|
function register(nativeViewId) {
|
|
2923
4086
|
viewId.value = nativeViewId;
|
|
2924
4087
|
sharedElementRegistry.set(elementId, nativeViewId);
|
|
@@ -2927,7 +4090,7 @@ function useSharedElementTransition(elementId) {
|
|
|
2927
4090
|
viewId.value = null;
|
|
2928
4091
|
sharedElementRegistry.delete(elementId);
|
|
2929
4092
|
}
|
|
2930
|
-
|
|
4093
|
+
onUnmounted18(() => {
|
|
2931
4094
|
unregister();
|
|
2932
4095
|
});
|
|
2933
4096
|
return {
|
|
@@ -2951,11 +4114,19 @@ function clearSharedElementRegistry() {
|
|
|
2951
4114
|
}
|
|
2952
4115
|
|
|
2953
4116
|
// src/composables/useIAP.ts
|
|
2954
|
-
import { ref as
|
|
4117
|
+
import { ref as ref28, onUnmounted as onUnmounted19 } from "@vue/runtime-core";
|
|
4118
|
+
function getErrorMessage(error) {
|
|
4119
|
+
if (error instanceof Error) return error.message;
|
|
4120
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4121
|
+
const message = error.message;
|
|
4122
|
+
if (typeof message === "string") return message;
|
|
4123
|
+
}
|
|
4124
|
+
return String(error);
|
|
4125
|
+
}
|
|
2955
4126
|
function useIAP() {
|
|
2956
|
-
const products =
|
|
2957
|
-
const isReady =
|
|
2958
|
-
const error =
|
|
4127
|
+
const products = ref28([]);
|
|
4128
|
+
const isReady = ref28(false);
|
|
4129
|
+
const error = ref28(null);
|
|
2959
4130
|
const cleanups = [];
|
|
2960
4131
|
const unsubscribe = NativeBridge.onGlobalEvent("iap:transactionUpdate", (payload) => {
|
|
2961
4132
|
if (payload.state === "failed" && payload.error) {
|
|
@@ -2966,7 +4137,7 @@ function useIAP() {
|
|
|
2966
4137
|
NativeBridge.invokeNativeModule("IAP", "initialize").then(() => {
|
|
2967
4138
|
isReady.value = true;
|
|
2968
4139
|
}).catch((err) => {
|
|
2969
|
-
error.value =
|
|
4140
|
+
error.value = getErrorMessage(err);
|
|
2970
4141
|
});
|
|
2971
4142
|
async function getProducts(skus) {
|
|
2972
4143
|
error.value = null;
|
|
@@ -2976,7 +4147,7 @@ function useIAP() {
|
|
|
2976
4147
|
products.value = productList;
|
|
2977
4148
|
return productList;
|
|
2978
4149
|
} catch (err) {
|
|
2979
|
-
error.value =
|
|
4150
|
+
error.value = getErrorMessage(err);
|
|
2980
4151
|
return [];
|
|
2981
4152
|
}
|
|
2982
4153
|
}
|
|
@@ -2985,7 +4156,7 @@ function useIAP() {
|
|
|
2985
4156
|
try {
|
|
2986
4157
|
return await NativeBridge.invokeNativeModule("IAP", "purchase", [sku]);
|
|
2987
4158
|
} catch (err) {
|
|
2988
|
-
error.value =
|
|
4159
|
+
error.value = getErrorMessage(err);
|
|
2989
4160
|
return null;
|
|
2990
4161
|
}
|
|
2991
4162
|
}
|
|
@@ -2994,7 +4165,7 @@ function useIAP() {
|
|
|
2994
4165
|
try {
|
|
2995
4166
|
return await NativeBridge.invokeNativeModule("IAP", "restorePurchases");
|
|
2996
4167
|
} catch (err) {
|
|
2997
|
-
error.value =
|
|
4168
|
+
error.value = getErrorMessage(err);
|
|
2998
4169
|
return [];
|
|
2999
4170
|
}
|
|
3000
4171
|
}
|
|
@@ -3003,7 +4174,7 @@ function useIAP() {
|
|
|
3003
4174
|
try {
|
|
3004
4175
|
return await NativeBridge.invokeNativeModule("IAP", "getActiveSubscriptions");
|
|
3005
4176
|
} catch (err) {
|
|
3006
|
-
error.value =
|
|
4177
|
+
error.value = getErrorMessage(err);
|
|
3007
4178
|
return [];
|
|
3008
4179
|
}
|
|
3009
4180
|
}
|
|
@@ -3012,7 +4183,7 @@ function useIAP() {
|
|
|
3012
4183
|
cleanups.push(unsub);
|
|
3013
4184
|
return unsub;
|
|
3014
4185
|
}
|
|
3015
|
-
|
|
4186
|
+
onUnmounted19(() => {
|
|
3016
4187
|
cleanups.forEach((fn) => fn());
|
|
3017
4188
|
cleanups.length = 0;
|
|
3018
4189
|
});
|
|
@@ -3029,11 +4200,32 @@ function useIAP() {
|
|
|
3029
4200
|
}
|
|
3030
4201
|
|
|
3031
4202
|
// src/composables/useAppleSignIn.ts
|
|
3032
|
-
import { ref as
|
|
4203
|
+
import { ref as ref29, onUnmounted as onUnmounted20 } from "@vue/runtime-core";
|
|
4204
|
+
function getErrorMessage2(error) {
|
|
4205
|
+
if (error instanceof Error) return error.message;
|
|
4206
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4207
|
+
const message = error.message;
|
|
4208
|
+
if (typeof message === "string") return message;
|
|
4209
|
+
}
|
|
4210
|
+
return String(error);
|
|
4211
|
+
}
|
|
4212
|
+
function normalizeSocialUser(value, provider) {
|
|
4213
|
+
if (typeof value !== "object" || value === null) return null;
|
|
4214
|
+
const payload = value;
|
|
4215
|
+
if (typeof payload.userId !== "string") return null;
|
|
4216
|
+
return {
|
|
4217
|
+
userId: payload.userId,
|
|
4218
|
+
email: typeof payload.email === "string" ? payload.email : void 0,
|
|
4219
|
+
fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
|
|
4220
|
+
identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
|
|
4221
|
+
authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
|
|
4222
|
+
provider
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
3033
4225
|
function useAppleSignIn() {
|
|
3034
|
-
const user =
|
|
3035
|
-
const isAuthenticated =
|
|
3036
|
-
const error =
|
|
4226
|
+
const user = ref29(null);
|
|
4227
|
+
const isAuthenticated = ref29(false);
|
|
4228
|
+
const error = ref29(null);
|
|
3037
4229
|
const cleanups = [];
|
|
3038
4230
|
const unsubscribe = NativeBridge.onGlobalEvent("auth:appleCredentialRevoked", () => {
|
|
3039
4231
|
user.value = null;
|
|
@@ -3041,8 +4233,9 @@ function useAppleSignIn() {
|
|
|
3041
4233
|
});
|
|
3042
4234
|
cleanups.push(unsubscribe);
|
|
3043
4235
|
NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["apple"]).then((result) => {
|
|
3044
|
-
|
|
3045
|
-
|
|
4236
|
+
const currentUser = normalizeSocialUser(result, "apple");
|
|
4237
|
+
if (currentUser) {
|
|
4238
|
+
user.value = currentUser;
|
|
3046
4239
|
isAuthenticated.value = true;
|
|
3047
4240
|
}
|
|
3048
4241
|
}).catch(() => {
|
|
@@ -3051,12 +4244,15 @@ function useAppleSignIn() {
|
|
|
3051
4244
|
error.value = null;
|
|
3052
4245
|
try {
|
|
3053
4246
|
const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithApple");
|
|
3054
|
-
const socialUser =
|
|
4247
|
+
const socialUser = normalizeSocialUser(result, "apple");
|
|
4248
|
+
if (!socialUser) {
|
|
4249
|
+
throw new Error("Invalid Apple Sign In response.");
|
|
4250
|
+
}
|
|
3055
4251
|
user.value = socialUser;
|
|
3056
4252
|
isAuthenticated.value = true;
|
|
3057
4253
|
return { success: true, user: socialUser };
|
|
3058
4254
|
} catch (err) {
|
|
3059
|
-
const message =
|
|
4255
|
+
const message = getErrorMessage2(err);
|
|
3060
4256
|
error.value = message;
|
|
3061
4257
|
return { success: false, error: message };
|
|
3062
4258
|
}
|
|
@@ -3068,10 +4264,10 @@ function useAppleSignIn() {
|
|
|
3068
4264
|
user.value = null;
|
|
3069
4265
|
isAuthenticated.value = false;
|
|
3070
4266
|
} catch (err) {
|
|
3071
|
-
error.value =
|
|
4267
|
+
error.value = getErrorMessage2(err);
|
|
3072
4268
|
}
|
|
3073
4269
|
}
|
|
3074
|
-
|
|
4270
|
+
onUnmounted20(() => {
|
|
3075
4271
|
cleanups.forEach((fn) => fn());
|
|
3076
4272
|
cleanups.length = 0;
|
|
3077
4273
|
});
|
|
@@ -3079,15 +4275,37 @@ function useAppleSignIn() {
|
|
|
3079
4275
|
}
|
|
3080
4276
|
|
|
3081
4277
|
// src/composables/useGoogleSignIn.ts
|
|
3082
|
-
import { ref as
|
|
4278
|
+
import { ref as ref30, onUnmounted as onUnmounted21 } from "@vue/runtime-core";
|
|
4279
|
+
function getErrorMessage3(error) {
|
|
4280
|
+
if (error instanceof Error) return error.message;
|
|
4281
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4282
|
+
const message = error.message;
|
|
4283
|
+
if (typeof message === "string") return message;
|
|
4284
|
+
}
|
|
4285
|
+
return String(error);
|
|
4286
|
+
}
|
|
4287
|
+
function normalizeSocialUser2(value) {
|
|
4288
|
+
if (typeof value !== "object" || value === null) return null;
|
|
4289
|
+
const payload = value;
|
|
4290
|
+
if (typeof payload.userId !== "string") return null;
|
|
4291
|
+
return {
|
|
4292
|
+
userId: payload.userId,
|
|
4293
|
+
email: typeof payload.email === "string" ? payload.email : void 0,
|
|
4294
|
+
fullName: typeof payload.fullName === "string" ? payload.fullName : void 0,
|
|
4295
|
+
identityToken: typeof payload.identityToken === "string" ? payload.identityToken : void 0,
|
|
4296
|
+
authorizationCode: typeof payload.authorizationCode === "string" ? payload.authorizationCode : void 0,
|
|
4297
|
+
provider: "google"
|
|
4298
|
+
};
|
|
4299
|
+
}
|
|
3083
4300
|
function useGoogleSignIn(clientId) {
|
|
3084
|
-
const user =
|
|
3085
|
-
const isAuthenticated =
|
|
3086
|
-
const error =
|
|
4301
|
+
const user = ref30(null);
|
|
4302
|
+
const isAuthenticated = ref30(false);
|
|
4303
|
+
const error = ref30(null);
|
|
3087
4304
|
const cleanups = [];
|
|
3088
4305
|
NativeBridge.invokeNativeModule("SocialAuth", "getCurrentUser", ["google"]).then((result) => {
|
|
3089
|
-
|
|
3090
|
-
|
|
4306
|
+
const currentUser = normalizeSocialUser2(result);
|
|
4307
|
+
if (currentUser) {
|
|
4308
|
+
user.value = currentUser;
|
|
3091
4309
|
isAuthenticated.value = true;
|
|
3092
4310
|
}
|
|
3093
4311
|
}).catch(() => {
|
|
@@ -3096,12 +4314,15 @@ function useGoogleSignIn(clientId) {
|
|
|
3096
4314
|
error.value = null;
|
|
3097
4315
|
try {
|
|
3098
4316
|
const result = await NativeBridge.invokeNativeModule("SocialAuth", "signInWithGoogle", [clientId]);
|
|
3099
|
-
const socialUser =
|
|
4317
|
+
const socialUser = normalizeSocialUser2(result);
|
|
4318
|
+
if (!socialUser) {
|
|
4319
|
+
throw new Error("Invalid Google Sign In response.");
|
|
4320
|
+
}
|
|
3100
4321
|
user.value = socialUser;
|
|
3101
4322
|
isAuthenticated.value = true;
|
|
3102
4323
|
return { success: true, user: socialUser };
|
|
3103
4324
|
} catch (err) {
|
|
3104
|
-
const message =
|
|
4325
|
+
const message = getErrorMessage3(err);
|
|
3105
4326
|
error.value = message;
|
|
3106
4327
|
return { success: false, error: message };
|
|
3107
4328
|
}
|
|
@@ -3113,10 +4334,10 @@ function useGoogleSignIn(clientId) {
|
|
|
3113
4334
|
user.value = null;
|
|
3114
4335
|
isAuthenticated.value = false;
|
|
3115
4336
|
} catch (err) {
|
|
3116
|
-
error.value =
|
|
4337
|
+
error.value = getErrorMessage3(err);
|
|
3117
4338
|
}
|
|
3118
4339
|
}
|
|
3119
|
-
|
|
4340
|
+
onUnmounted21(() => {
|
|
3120
4341
|
cleanups.forEach((fn) => fn());
|
|
3121
4342
|
cleanups.length = 0;
|
|
3122
4343
|
});
|
|
@@ -3124,17 +4345,17 @@ function useGoogleSignIn(clientId) {
|
|
|
3124
4345
|
}
|
|
3125
4346
|
|
|
3126
4347
|
// src/composables/useBackgroundTask.ts
|
|
3127
|
-
import { ref as
|
|
4348
|
+
import { ref as ref31, onUnmounted as onUnmounted22 } from "@vue/runtime-core";
|
|
3128
4349
|
function useBackgroundTask() {
|
|
3129
4350
|
const taskHandlers = /* @__PURE__ */ new Map();
|
|
3130
|
-
const defaultHandler =
|
|
4351
|
+
const defaultHandler = ref31(null);
|
|
3131
4352
|
const unsubscribe = NativeBridge.onGlobalEvent("background:taskExecute", (payload) => {
|
|
3132
4353
|
const handler = taskHandlers.get(payload.taskId) || defaultHandler.value;
|
|
3133
4354
|
if (handler) {
|
|
3134
4355
|
handler(payload.taskId);
|
|
3135
4356
|
}
|
|
3136
4357
|
});
|
|
3137
|
-
|
|
4358
|
+
onUnmounted22(unsubscribe);
|
|
3138
4359
|
function registerTask(taskId) {
|
|
3139
4360
|
return NativeBridge.invokeNativeModule("BackgroundTask", "registerTask", [taskId]).then(() => void 0);
|
|
3140
4361
|
}
|
|
@@ -3173,20 +4394,28 @@ function useBackgroundTask() {
|
|
|
3173
4394
|
}
|
|
3174
4395
|
|
|
3175
4396
|
// src/composables/useOTAUpdate.ts
|
|
3176
|
-
import { ref as
|
|
4397
|
+
import { ref as ref32, onUnmounted as onUnmounted23 } from "@vue/runtime-core";
|
|
4398
|
+
function getErrorMessage4(error) {
|
|
4399
|
+
if (error instanceof Error) return error.message;
|
|
4400
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4401
|
+
const message = error.message;
|
|
4402
|
+
if (typeof message === "string") return message;
|
|
4403
|
+
}
|
|
4404
|
+
return String(error);
|
|
4405
|
+
}
|
|
3177
4406
|
function useOTAUpdate(serverUrl) {
|
|
3178
|
-
const currentVersion =
|
|
3179
|
-
const availableVersion =
|
|
3180
|
-
const downloadProgress =
|
|
3181
|
-
const isChecking =
|
|
3182
|
-
const isDownloading =
|
|
3183
|
-
const status =
|
|
3184
|
-
const error =
|
|
4407
|
+
const currentVersion = ref32("embedded");
|
|
4408
|
+
const availableVersion = ref32(null);
|
|
4409
|
+
const downloadProgress = ref32(0);
|
|
4410
|
+
const isChecking = ref32(false);
|
|
4411
|
+
const isDownloading = ref32(false);
|
|
4412
|
+
const status = ref32("idle");
|
|
4413
|
+
const error = ref32(null);
|
|
3185
4414
|
let lastUpdateInfo = null;
|
|
3186
4415
|
const unsubscribe = NativeBridge.onGlobalEvent("ota:downloadProgress", (payload) => {
|
|
3187
4416
|
downloadProgress.value = payload.progress;
|
|
3188
4417
|
});
|
|
3189
|
-
|
|
4418
|
+
onUnmounted23(unsubscribe);
|
|
3190
4419
|
NativeBridge.invokeNativeModule("OTA", "getCurrentVersion", []).then((info) => {
|
|
3191
4420
|
currentVersion.value = info.version;
|
|
3192
4421
|
}).catch(() => {
|
|
@@ -3206,7 +4435,7 @@ function useOTAUpdate(serverUrl) {
|
|
|
3206
4435
|
status.value = info.updateAvailable ? "idle" : "idle";
|
|
3207
4436
|
return info;
|
|
3208
4437
|
} catch (err) {
|
|
3209
|
-
error.value =
|
|
4438
|
+
error.value = getErrorMessage4(err);
|
|
3210
4439
|
status.value = "error";
|
|
3211
4440
|
throw err;
|
|
3212
4441
|
} finally {
|
|
@@ -3232,7 +4461,7 @@ function useOTAUpdate(serverUrl) {
|
|
|
3232
4461
|
} catch (err) {
|
|
3233
4462
|
await NativeBridge.invokeNativeModule("OTA", "cleanupPartialDownload", []).catch(() => {
|
|
3234
4463
|
});
|
|
3235
|
-
error.value =
|
|
4464
|
+
error.value = getErrorMessage4(err);
|
|
3236
4465
|
status.value = "error";
|
|
3237
4466
|
throw err;
|
|
3238
4467
|
} finally {
|
|
@@ -3248,7 +4477,7 @@ function useOTAUpdate(serverUrl) {
|
|
|
3248
4477
|
await NativeBridge.invokeNativeModule("OTA", "verifyBundle", []);
|
|
3249
4478
|
} catch (err) {
|
|
3250
4479
|
status.value = "error";
|
|
3251
|
-
error.value = "Bundle verification failed: " + (err
|
|
4480
|
+
error.value = "Bundle verification failed: " + getErrorMessage4(err);
|
|
3252
4481
|
throw err;
|
|
3253
4482
|
}
|
|
3254
4483
|
try {
|
|
@@ -3258,7 +4487,7 @@ function useOTAUpdate(serverUrl) {
|
|
|
3258
4487
|
availableVersion.value = null;
|
|
3259
4488
|
status.value = "idle";
|
|
3260
4489
|
} catch (err) {
|
|
3261
|
-
error.value =
|
|
4490
|
+
error.value = getErrorMessage4(err);
|
|
3262
4491
|
status.value = "error";
|
|
3263
4492
|
throw err;
|
|
3264
4493
|
}
|
|
@@ -3271,7 +4500,7 @@ function useOTAUpdate(serverUrl) {
|
|
|
3271
4500
|
currentVersion.value = info.version;
|
|
3272
4501
|
status.value = "idle";
|
|
3273
4502
|
} catch (err) {
|
|
3274
|
-
error.value =
|
|
4503
|
+
error.value = getErrorMessage4(err);
|
|
3275
4504
|
status.value = "error";
|
|
3276
4505
|
throw err;
|
|
3277
4506
|
}
|
|
@@ -3298,13 +4527,21 @@ function useOTAUpdate(serverUrl) {
|
|
|
3298
4527
|
}
|
|
3299
4528
|
|
|
3300
4529
|
// src/composables/useBluetooth.ts
|
|
3301
|
-
import { ref as
|
|
4530
|
+
import { ref as ref33, onUnmounted as onUnmounted24 } from "@vue/runtime-core";
|
|
4531
|
+
function getErrorMessage5(error) {
|
|
4532
|
+
if (error instanceof Error) return error.message;
|
|
4533
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4534
|
+
const message = error.message;
|
|
4535
|
+
if (typeof message === "string") return message;
|
|
4536
|
+
}
|
|
4537
|
+
return String(error);
|
|
4538
|
+
}
|
|
3302
4539
|
function useBluetooth() {
|
|
3303
|
-
const devices =
|
|
3304
|
-
const connectedDevice =
|
|
3305
|
-
const isScanning =
|
|
3306
|
-
const isAvailable =
|
|
3307
|
-
const error =
|
|
4540
|
+
const devices = ref33([]);
|
|
4541
|
+
const connectedDevice = ref33(null);
|
|
4542
|
+
const isScanning = ref33(false);
|
|
4543
|
+
const isAvailable = ref33(false);
|
|
4544
|
+
const error = ref33(null);
|
|
3308
4545
|
const cleanups = [];
|
|
3309
4546
|
NativeBridge.invokeNativeModule("Bluetooth", "getState").then((state) => {
|
|
3310
4547
|
isAvailable.value = state === "poweredOn";
|
|
@@ -3343,7 +4580,7 @@ function useBluetooth() {
|
|
|
3343
4580
|
try {
|
|
3344
4581
|
await NativeBridge.invokeNativeModule("Bluetooth", "startScan", [serviceUUIDs]);
|
|
3345
4582
|
} catch (e) {
|
|
3346
|
-
error.value =
|
|
4583
|
+
error.value = getErrorMessage5(e);
|
|
3347
4584
|
isScanning.value = false;
|
|
3348
4585
|
}
|
|
3349
4586
|
}
|
|
@@ -3383,7 +4620,7 @@ function useBluetooth() {
|
|
|
3383
4620
|
]);
|
|
3384
4621
|
};
|
|
3385
4622
|
}
|
|
3386
|
-
|
|
4623
|
+
onUnmounted24(() => {
|
|
3387
4624
|
if (isScanning.value) {
|
|
3388
4625
|
NativeBridge.invokeNativeModule("Bluetooth", "stopScan").catch(() => {
|
|
3389
4626
|
});
|
|
@@ -3408,17 +4645,25 @@ function useBluetooth() {
|
|
|
3408
4645
|
}
|
|
3409
4646
|
|
|
3410
4647
|
// src/composables/useCalendar.ts
|
|
3411
|
-
import { ref as
|
|
4648
|
+
import { ref as ref34 } from "@vue/runtime-core";
|
|
4649
|
+
function getErrorMessage6(error) {
|
|
4650
|
+
if (error instanceof Error) return error.message;
|
|
4651
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4652
|
+
const message = error.message;
|
|
4653
|
+
if (typeof message === "string") return message;
|
|
4654
|
+
}
|
|
4655
|
+
return String(error);
|
|
4656
|
+
}
|
|
3412
4657
|
function useCalendar() {
|
|
3413
|
-
const hasAccess =
|
|
3414
|
-
const error =
|
|
4658
|
+
const hasAccess = ref34(false);
|
|
4659
|
+
const error = ref34(null);
|
|
3415
4660
|
async function requestAccess() {
|
|
3416
4661
|
try {
|
|
3417
4662
|
const result = await NativeBridge.invokeNativeModule("Calendar", "requestAccess");
|
|
3418
4663
|
hasAccess.value = result.granted;
|
|
3419
4664
|
return result.granted;
|
|
3420
4665
|
} catch (e) {
|
|
3421
|
-
error.value =
|
|
4666
|
+
error.value = getErrorMessage6(e);
|
|
3422
4667
|
return false;
|
|
3423
4668
|
}
|
|
3424
4669
|
}
|
|
@@ -3444,17 +4689,25 @@ function useCalendar() {
|
|
|
3444
4689
|
}
|
|
3445
4690
|
|
|
3446
4691
|
// src/composables/useContacts.ts
|
|
3447
|
-
import { ref as
|
|
4692
|
+
import { ref as ref35 } from "@vue/runtime-core";
|
|
4693
|
+
function getErrorMessage7(error) {
|
|
4694
|
+
if (error instanceof Error) return error.message;
|
|
4695
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
4696
|
+
const message = error.message;
|
|
4697
|
+
if (typeof message === "string") return message;
|
|
4698
|
+
}
|
|
4699
|
+
return String(error);
|
|
4700
|
+
}
|
|
3448
4701
|
function useContacts() {
|
|
3449
|
-
const hasAccess =
|
|
3450
|
-
const error =
|
|
4702
|
+
const hasAccess = ref35(false);
|
|
4703
|
+
const error = ref35(null);
|
|
3451
4704
|
async function requestAccess() {
|
|
3452
4705
|
try {
|
|
3453
4706
|
const result = await NativeBridge.invokeNativeModule("Contacts", "requestAccess");
|
|
3454
4707
|
hasAccess.value = result.granted;
|
|
3455
4708
|
return result.granted;
|
|
3456
4709
|
} catch (e) {
|
|
3457
|
-
error.value =
|
|
4710
|
+
error.value = getErrorMessage7(e);
|
|
3458
4711
|
return false;
|
|
3459
4712
|
}
|
|
3460
4713
|
}
|
|
@@ -3473,39 +4726,500 @@ function useContacts() {
|
|
|
3473
4726
|
return { requestAccess, getContacts, getContact, createContact, deleteContact, hasAccess, error };
|
|
3474
4727
|
}
|
|
3475
4728
|
|
|
4729
|
+
// src/composables/useWindow.ts
|
|
4730
|
+
function useWindow() {
|
|
4731
|
+
const { isMacOS } = usePlatform();
|
|
4732
|
+
async function setTitle(title) {
|
|
4733
|
+
if (!isMacOS) return;
|
|
4734
|
+
await NativeBridge.invokeNativeModule("Window", "setTitle", [title]);
|
|
4735
|
+
}
|
|
4736
|
+
async function setSize(width, height) {
|
|
4737
|
+
if (!isMacOS) return;
|
|
4738
|
+
await NativeBridge.invokeNativeModule("Window", "setSize", [width, height]);
|
|
4739
|
+
}
|
|
4740
|
+
async function center() {
|
|
4741
|
+
if (!isMacOS) return;
|
|
4742
|
+
await NativeBridge.invokeNativeModule("Window", "center", []);
|
|
4743
|
+
}
|
|
4744
|
+
async function minimize() {
|
|
4745
|
+
if (!isMacOS) return;
|
|
4746
|
+
await NativeBridge.invokeNativeModule("Window", "minimize", []);
|
|
4747
|
+
}
|
|
4748
|
+
async function toggleFullScreen() {
|
|
4749
|
+
if (!isMacOS) return;
|
|
4750
|
+
await NativeBridge.invokeNativeModule("Window", "toggleFullScreen", []);
|
|
4751
|
+
}
|
|
4752
|
+
async function close() {
|
|
4753
|
+
if (!isMacOS) return;
|
|
4754
|
+
await NativeBridge.invokeNativeModule("Window", "close", []);
|
|
4755
|
+
}
|
|
4756
|
+
async function getInfo() {
|
|
4757
|
+
if (!isMacOS) return null;
|
|
4758
|
+
return await NativeBridge.invokeNativeModule("Window", "getInfo", []);
|
|
4759
|
+
}
|
|
4760
|
+
return { setTitle, setSize, center, minimize, toggleFullScreen, close, getInfo };
|
|
4761
|
+
}
|
|
4762
|
+
|
|
4763
|
+
// src/composables/useMenu.ts
|
|
4764
|
+
function useMenu() {
|
|
4765
|
+
const { isMacOS } = usePlatform();
|
|
4766
|
+
async function setAppMenu(sections) {
|
|
4767
|
+
if (!isMacOS) return;
|
|
4768
|
+
await NativeBridge.invokeNativeModule("Menu", "setAppMenu", [sections]);
|
|
4769
|
+
}
|
|
4770
|
+
async function showContextMenu(items) {
|
|
4771
|
+
if (!isMacOS) return;
|
|
4772
|
+
await NativeBridge.invokeNativeModule("Menu", "showContextMenu", [items]);
|
|
4773
|
+
}
|
|
4774
|
+
function onMenuItemClick(callback) {
|
|
4775
|
+
if (!isMacOS) return () => {
|
|
4776
|
+
};
|
|
4777
|
+
return NativeBridge.onGlobalEvent("menu:itemClick", (payload) => {
|
|
4778
|
+
callback(payload.id ?? "", payload.title ?? "");
|
|
4779
|
+
});
|
|
4780
|
+
}
|
|
4781
|
+
return { setAppMenu, showContextMenu, onMenuItemClick };
|
|
4782
|
+
}
|
|
4783
|
+
|
|
4784
|
+
// src/composables/useFileDialog.ts
|
|
4785
|
+
function useFileDialog() {
|
|
4786
|
+
const { isMacOS } = usePlatform();
|
|
4787
|
+
async function openFile(options) {
|
|
4788
|
+
if (!isMacOS) return null;
|
|
4789
|
+
return await NativeBridge.invokeNativeModule("FileDialog", "openFile", [options || {}]);
|
|
4790
|
+
}
|
|
4791
|
+
async function openDirectory(options) {
|
|
4792
|
+
if (!isMacOS) return null;
|
|
4793
|
+
return await NativeBridge.invokeNativeModule("FileDialog", "openDirectory", [options || {}]);
|
|
4794
|
+
}
|
|
4795
|
+
async function saveFile(options) {
|
|
4796
|
+
if (!isMacOS) return null;
|
|
4797
|
+
return await NativeBridge.invokeNativeModule("FileDialog", "saveFile", [options || {}]);
|
|
4798
|
+
}
|
|
4799
|
+
return { openFile, openDirectory, saveFile };
|
|
4800
|
+
}
|
|
4801
|
+
|
|
4802
|
+
// src/composables/useDragDrop.ts
|
|
4803
|
+
import { ref as ref36, readonly } from "@vue/runtime-core";
|
|
4804
|
+
function useDragDrop() {
|
|
4805
|
+
const { isMacOS } = usePlatform();
|
|
4806
|
+
const isDragging = ref36(false);
|
|
4807
|
+
async function enableDropZone() {
|
|
4808
|
+
if (!isMacOS) return;
|
|
4809
|
+
await NativeBridge.invokeNativeModule("DragDrop", "enableDropZone", []);
|
|
4810
|
+
}
|
|
4811
|
+
function onDrop(callback) {
|
|
4812
|
+
if (!isMacOS) return () => {
|
|
4813
|
+
};
|
|
4814
|
+
return NativeBridge.onGlobalEvent("dragdrop:drop", (payload) => {
|
|
4815
|
+
const files = Array.isArray(payload.files) ? payload.files.filter((file) => typeof file === "string") : [];
|
|
4816
|
+
callback(files);
|
|
4817
|
+
});
|
|
4818
|
+
}
|
|
4819
|
+
function onDragEnter(callback) {
|
|
4820
|
+
if (!isMacOS) return () => {
|
|
4821
|
+
};
|
|
4822
|
+
return NativeBridge.onGlobalEvent("dragdrop:enter", () => {
|
|
4823
|
+
isDragging.value = true;
|
|
4824
|
+
callback();
|
|
4825
|
+
});
|
|
4826
|
+
}
|
|
4827
|
+
function onDragLeave(callback) {
|
|
4828
|
+
if (!isMacOS) return () => {
|
|
4829
|
+
};
|
|
4830
|
+
return NativeBridge.onGlobalEvent("dragdrop:leave", () => {
|
|
4831
|
+
isDragging.value = false;
|
|
4832
|
+
callback();
|
|
4833
|
+
});
|
|
4834
|
+
}
|
|
4835
|
+
return { enableDropZone, onDrop, onDragEnter, onDragLeave, isDragging: readonly(isDragging) };
|
|
4836
|
+
}
|
|
4837
|
+
|
|
4838
|
+
// src/composables/useTeleport.ts
|
|
4839
|
+
function useTeleport(target) {
|
|
4840
|
+
const teleport = (node) => {
|
|
4841
|
+
NativeBridge.teleportTo(target, node.id);
|
|
4842
|
+
};
|
|
4843
|
+
return { teleport };
|
|
4844
|
+
}
|
|
4845
|
+
|
|
4846
|
+
// src/composables/useGesture.ts
|
|
4847
|
+
import { ref as ref37, onUnmounted as onUnmounted25 } from "@vue/runtime-core";
|
|
4848
|
+
function hasViewId2(value) {
|
|
4849
|
+
return typeof value === "object" && value !== null && "id" in value && typeof value.id === "number";
|
|
4850
|
+
}
|
|
4851
|
+
function isGestureRef(target) {
|
|
4852
|
+
return typeof target === "object" && target !== null && "value" in target;
|
|
4853
|
+
}
|
|
4854
|
+
function resolveViewId2(target) {
|
|
4855
|
+
if (typeof target === "number") return target;
|
|
4856
|
+
if (isGestureRef(target)) {
|
|
4857
|
+
const val = target.value;
|
|
4858
|
+
if (hasViewId2(val)) return val.id;
|
|
4859
|
+
throw new Error("[useGesture] Target ref has no .value.id \u2014 is the ref attached to a component?");
|
|
4860
|
+
}
|
|
4861
|
+
if (hasViewId2(target)) return target.id;
|
|
4862
|
+
throw new Error("[useGesture] Invalid target. Pass a number, template ref, or NativeNode.");
|
|
4863
|
+
}
|
|
4864
|
+
var GestureManager = class {
|
|
4865
|
+
constructor() {
|
|
4866
|
+
this.nodeId = null;
|
|
4867
|
+
this.handlers = /* @__PURE__ */ new Map();
|
|
4868
|
+
this.disposables = [];
|
|
4869
|
+
}
|
|
4870
|
+
attach(target) {
|
|
4871
|
+
this.nodeId = resolveViewId2(target);
|
|
4872
|
+
}
|
|
4873
|
+
on(event, callback, config) {
|
|
4874
|
+
if (!this.nodeId) {
|
|
4875
|
+
console.warn("[useGesture] Cannot add listener: not attached to a view. Call attach() first or use a ref.");
|
|
4876
|
+
return () => {
|
|
4877
|
+
};
|
|
4878
|
+
}
|
|
4879
|
+
if (!this.handlers.has(event)) {
|
|
4880
|
+
this.handlers.set(event, /* @__PURE__ */ new Set());
|
|
4881
|
+
}
|
|
4882
|
+
this.handlers.get(event).add(callback);
|
|
4883
|
+
NativeBridge.addEventListener(this.nodeId, event, (payload) => {
|
|
4884
|
+
if (config?.enabled === false) return;
|
|
4885
|
+
callback(payload);
|
|
4886
|
+
});
|
|
4887
|
+
const dispose = () => {
|
|
4888
|
+
this.handlers.get(event)?.delete(callback);
|
|
4889
|
+
if (this.nodeId) {
|
|
4890
|
+
NativeBridge.removeEventListener(this.nodeId, event);
|
|
4891
|
+
}
|
|
4892
|
+
};
|
|
4893
|
+
this.disposables.push(dispose);
|
|
4894
|
+
return dispose;
|
|
4895
|
+
}
|
|
4896
|
+
detach() {
|
|
4897
|
+
for (const dispose of this.disposables) {
|
|
4898
|
+
dispose();
|
|
4899
|
+
}
|
|
4900
|
+
this.disposables = [];
|
|
4901
|
+
this.handlers.clear();
|
|
4902
|
+
this.nodeId = null;
|
|
4903
|
+
}
|
|
4904
|
+
};
|
|
4905
|
+
function useGesture(target, options = {}) {
|
|
4906
|
+
const pan = ref37(null);
|
|
4907
|
+
const pinch = ref37(null);
|
|
4908
|
+
const rotate = ref37(null);
|
|
4909
|
+
const swipeLeft = ref37(null);
|
|
4910
|
+
const swipeRight = ref37(null);
|
|
4911
|
+
const swipeUp = ref37(null);
|
|
4912
|
+
const swipeDown = ref37(null);
|
|
4913
|
+
const press = ref37(null);
|
|
4914
|
+
const longPress = ref37(null);
|
|
4915
|
+
const doubleTap = ref37(null);
|
|
4916
|
+
const forceTouch = ref37(null);
|
|
4917
|
+
const hover = ref37(null);
|
|
4918
|
+
const gestureState = ref37(null);
|
|
4919
|
+
const activeGesture = ref37(null);
|
|
4920
|
+
const isGesturing = ref37(false);
|
|
4921
|
+
const manager = new GestureManager();
|
|
4922
|
+
const cleanupFns = [];
|
|
4923
|
+
function attach(t) {
|
|
4924
|
+
manager.attach(t);
|
|
4925
|
+
setupListeners();
|
|
4926
|
+
}
|
|
4927
|
+
function detach() {
|
|
4928
|
+
for (const fn of cleanupFns) fn();
|
|
4929
|
+
cleanupFns.length = 0;
|
|
4930
|
+
manager.detach();
|
|
4931
|
+
pan.value = null;
|
|
4932
|
+
pinch.value = null;
|
|
4933
|
+
rotate.value = null;
|
|
4934
|
+
swipeLeft.value = null;
|
|
4935
|
+
swipeRight.value = null;
|
|
4936
|
+
swipeUp.value = null;
|
|
4937
|
+
swipeDown.value = null;
|
|
4938
|
+
press.value = null;
|
|
4939
|
+
longPress.value = null;
|
|
4940
|
+
doubleTap.value = null;
|
|
4941
|
+
forceTouch.value = null;
|
|
4942
|
+
hover.value = null;
|
|
4943
|
+
gestureState.value = null;
|
|
4944
|
+
activeGesture.value = null;
|
|
4945
|
+
isGesturing.value = false;
|
|
4946
|
+
}
|
|
4947
|
+
function normalizeConfig(opt) {
|
|
4948
|
+
return typeof opt === "boolean" ? { enabled: opt } : opt ?? {};
|
|
4949
|
+
}
|
|
4950
|
+
function on(event, callback) {
|
|
4951
|
+
return manager.on(event, callback);
|
|
4952
|
+
}
|
|
4953
|
+
function setupListeners() {
|
|
4954
|
+
if (options.pan) {
|
|
4955
|
+
const cfg = normalizeConfig(options.pan);
|
|
4956
|
+
const dispose = manager.on("pan", (state) => {
|
|
4957
|
+
pan.value = state;
|
|
4958
|
+
gestureState.value = state;
|
|
4959
|
+
activeGesture.value = "pan";
|
|
4960
|
+
isGesturing.value = state.state === "began" || state.state === "changed";
|
|
4961
|
+
}, cfg);
|
|
4962
|
+
cleanupFns.push(dispose);
|
|
4963
|
+
}
|
|
4964
|
+
if (options.pinch) {
|
|
4965
|
+
const cfg = normalizeConfig(options.pinch);
|
|
4966
|
+
const dispose = manager.on("pinch", (state) => {
|
|
4967
|
+
pinch.value = state;
|
|
4968
|
+
gestureState.value = state;
|
|
4969
|
+
activeGesture.value = "pinch";
|
|
4970
|
+
isGesturing.value = state.state === "began" || state.state === "changed";
|
|
4971
|
+
}, cfg);
|
|
4972
|
+
cleanupFns.push(dispose);
|
|
4973
|
+
}
|
|
4974
|
+
if (options.rotate) {
|
|
4975
|
+
const cfg = normalizeConfig(options.rotate);
|
|
4976
|
+
const dispose = manager.on("rotate", (state) => {
|
|
4977
|
+
rotate.value = state;
|
|
4978
|
+
gestureState.value = state;
|
|
4979
|
+
activeGesture.value = "rotate";
|
|
4980
|
+
isGesturing.value = state.state === "began" || state.state === "changed";
|
|
4981
|
+
}, cfg);
|
|
4982
|
+
cleanupFns.push(dispose);
|
|
4983
|
+
}
|
|
4984
|
+
if (options.swipeLeft) {
|
|
4985
|
+
const cfg = normalizeConfig(options.swipeLeft);
|
|
4986
|
+
const dispose = manager.on("swipeLeft", (state) => {
|
|
4987
|
+
swipeLeft.value = state;
|
|
4988
|
+
gestureState.value = state;
|
|
4989
|
+
activeGesture.value = "swipeLeft";
|
|
4990
|
+
isGesturing.value = false;
|
|
4991
|
+
}, cfg);
|
|
4992
|
+
cleanupFns.push(dispose);
|
|
4993
|
+
}
|
|
4994
|
+
if (options.swipeRight) {
|
|
4995
|
+
const cfg = normalizeConfig(options.swipeRight);
|
|
4996
|
+
const dispose = manager.on("swipeRight", (state) => {
|
|
4997
|
+
swipeRight.value = state;
|
|
4998
|
+
gestureState.value = state;
|
|
4999
|
+
activeGesture.value = "swipeRight";
|
|
5000
|
+
isGesturing.value = false;
|
|
5001
|
+
}, cfg);
|
|
5002
|
+
cleanupFns.push(dispose);
|
|
5003
|
+
}
|
|
5004
|
+
if (options.swipeUp) {
|
|
5005
|
+
const cfg = normalizeConfig(options.swipeUp);
|
|
5006
|
+
const dispose = manager.on("swipeUp", (state) => {
|
|
5007
|
+
swipeUp.value = state;
|
|
5008
|
+
gestureState.value = state;
|
|
5009
|
+
activeGesture.value = "swipeUp";
|
|
5010
|
+
isGesturing.value = false;
|
|
5011
|
+
}, cfg);
|
|
5012
|
+
cleanupFns.push(dispose);
|
|
5013
|
+
}
|
|
5014
|
+
if (options.swipeDown) {
|
|
5015
|
+
const cfg = normalizeConfig(options.swipeDown);
|
|
5016
|
+
const dispose = manager.on("swipeDown", (state) => {
|
|
5017
|
+
swipeDown.value = state;
|
|
5018
|
+
gestureState.value = state;
|
|
5019
|
+
activeGesture.value = "swipeDown";
|
|
5020
|
+
isGesturing.value = false;
|
|
5021
|
+
}, cfg);
|
|
5022
|
+
cleanupFns.push(dispose);
|
|
5023
|
+
}
|
|
5024
|
+
if (options.press) {
|
|
5025
|
+
const cfg = normalizeConfig(options.press);
|
|
5026
|
+
const dispose = manager.on("press", (state) => {
|
|
5027
|
+
press.value = state;
|
|
5028
|
+
gestureState.value = state;
|
|
5029
|
+
activeGesture.value = "press";
|
|
5030
|
+
isGesturing.value = false;
|
|
5031
|
+
}, cfg);
|
|
5032
|
+
cleanupFns.push(dispose);
|
|
5033
|
+
}
|
|
5034
|
+
if (options.longPress) {
|
|
5035
|
+
const cfg = normalizeConfig(options.longPress);
|
|
5036
|
+
const dispose = manager.on("longPress", (state) => {
|
|
5037
|
+
longPress.value = state;
|
|
5038
|
+
gestureState.value = state;
|
|
5039
|
+
activeGesture.value = "longPress";
|
|
5040
|
+
isGesturing.value = false;
|
|
5041
|
+
}, cfg);
|
|
5042
|
+
cleanupFns.push(dispose);
|
|
5043
|
+
}
|
|
5044
|
+
if (options.doubleTap) {
|
|
5045
|
+
const cfg = normalizeConfig(options.doubleTap);
|
|
5046
|
+
const dispose = manager.on("doubleTap", (state) => {
|
|
5047
|
+
doubleTap.value = state;
|
|
5048
|
+
gestureState.value = state;
|
|
5049
|
+
activeGesture.value = "doubleTap";
|
|
5050
|
+
isGesturing.value = false;
|
|
5051
|
+
}, cfg);
|
|
5052
|
+
cleanupFns.push(dispose);
|
|
5053
|
+
}
|
|
5054
|
+
if (options.forceTouch) {
|
|
5055
|
+
const cfg = normalizeConfig(options.forceTouch);
|
|
5056
|
+
const dispose = manager.on("forceTouch", (state) => {
|
|
5057
|
+
forceTouch.value = state;
|
|
5058
|
+
gestureState.value = state;
|
|
5059
|
+
activeGesture.value = "forceTouch";
|
|
5060
|
+
isGesturing.value = state.stage > 0;
|
|
5061
|
+
}, cfg);
|
|
5062
|
+
cleanupFns.push(dispose);
|
|
5063
|
+
}
|
|
5064
|
+
if (options.hover) {
|
|
5065
|
+
const cfg = normalizeConfig(options.hover);
|
|
5066
|
+
const dispose = manager.on("hover", (state) => {
|
|
5067
|
+
hover.value = state;
|
|
5068
|
+
gestureState.value = state;
|
|
5069
|
+
activeGesture.value = "hover";
|
|
5070
|
+
isGesturing.value = state.state !== "exited";
|
|
5071
|
+
}, cfg);
|
|
5072
|
+
cleanupFns.push(dispose);
|
|
5073
|
+
}
|
|
5074
|
+
}
|
|
5075
|
+
onUnmounted25(() => {
|
|
5076
|
+
detach();
|
|
5077
|
+
});
|
|
5078
|
+
if (target !== void 0) {
|
|
5079
|
+
attach(target);
|
|
5080
|
+
}
|
|
5081
|
+
return {
|
|
5082
|
+
pan,
|
|
5083
|
+
pinch,
|
|
5084
|
+
rotate,
|
|
5085
|
+
swipeLeft,
|
|
5086
|
+
swipeRight,
|
|
5087
|
+
swipeUp,
|
|
5088
|
+
swipeDown,
|
|
5089
|
+
press,
|
|
5090
|
+
longPress,
|
|
5091
|
+
doubleTap,
|
|
5092
|
+
forceTouch,
|
|
5093
|
+
hover,
|
|
5094
|
+
gestureState,
|
|
5095
|
+
activeGesture,
|
|
5096
|
+
isGesturing,
|
|
5097
|
+
attach,
|
|
5098
|
+
detach,
|
|
5099
|
+
on
|
|
5100
|
+
};
|
|
5101
|
+
}
|
|
5102
|
+
function useComposedGestures(target, options = {}) {
|
|
5103
|
+
const pan = ref37(null);
|
|
5104
|
+
const pinch = ref37(null);
|
|
5105
|
+
const rotate = ref37(null);
|
|
5106
|
+
const gestureState = ref37(null);
|
|
5107
|
+
const activeGesture = ref37(null);
|
|
5108
|
+
const isGesturing = ref37(false);
|
|
5109
|
+
const isPinchingAndRotating = ref37(false);
|
|
5110
|
+
const isPanningAndPinching = ref37(false);
|
|
5111
|
+
const manager = new GestureManager();
|
|
5112
|
+
manager.attach(target);
|
|
5113
|
+
const panConfig = typeof options.pan === "object" ? options.pan : {};
|
|
5114
|
+
const pinchConfig = typeof options.pinch === "object" ? options.pinch : {};
|
|
5115
|
+
const rotateConfig = typeof options.rotate === "object" ? options.rotate : {};
|
|
5116
|
+
const cleanupFns = [];
|
|
5117
|
+
if (options.pan !== false) {
|
|
5118
|
+
cleanupFns.push(manager.on("pan", (state) => {
|
|
5119
|
+
pan.value = state;
|
|
5120
|
+
gestureState.value = state;
|
|
5121
|
+
activeGesture.value = "pan";
|
|
5122
|
+
isGesturing.value = state.state === "began" || state.state === "changed";
|
|
5123
|
+
isPanningAndPinching.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
|
|
5124
|
+
}, panConfig));
|
|
5125
|
+
}
|
|
5126
|
+
if (options.pinch !== false) {
|
|
5127
|
+
cleanupFns.push(manager.on("pinch", (state) => {
|
|
5128
|
+
pinch.value = state;
|
|
5129
|
+
gestureState.value = state;
|
|
5130
|
+
activeGesture.value = "pinch";
|
|
5131
|
+
isGesturing.value = state.state === "began" || state.state === "changed";
|
|
5132
|
+
isPinchingAndRotating.value = rotate.value !== null && (state.state === "began" || state.state === "changed");
|
|
5133
|
+
isPanningAndPinching.value = pan.value !== null && (state.state === "began" || state.state === "changed");
|
|
5134
|
+
}, pinchConfig));
|
|
5135
|
+
}
|
|
5136
|
+
if (options.rotate !== false) {
|
|
5137
|
+
cleanupFns.push(manager.on("rotate", (state) => {
|
|
5138
|
+
rotate.value = state;
|
|
5139
|
+
gestureState.value = state;
|
|
5140
|
+
activeGesture.value = "rotate";
|
|
5141
|
+
isGesturing.value = state.state === "began" || state.state === "changed";
|
|
5142
|
+
isPinchingAndRotating.value = pinch.value !== null && (state.state === "began" || state.state === "changed");
|
|
5143
|
+
}, rotateConfig));
|
|
5144
|
+
}
|
|
5145
|
+
onUnmounted25(() => {
|
|
5146
|
+
for (const fn of cleanupFns) fn();
|
|
5147
|
+
manager.detach();
|
|
5148
|
+
});
|
|
5149
|
+
return {
|
|
5150
|
+
pan,
|
|
5151
|
+
pinch,
|
|
5152
|
+
rotate,
|
|
5153
|
+
gestureState,
|
|
5154
|
+
activeGesture,
|
|
5155
|
+
isGesturing,
|
|
5156
|
+
isPinchingAndRotating,
|
|
5157
|
+
isPanningAndPinching
|
|
5158
|
+
};
|
|
5159
|
+
}
|
|
5160
|
+
|
|
5161
|
+
// src/theme.ts
|
|
5162
|
+
import {
|
|
5163
|
+
inject as inject3,
|
|
5164
|
+
provide as provide3,
|
|
5165
|
+
computed as computed3,
|
|
5166
|
+
defineComponent as defineComponent35,
|
|
5167
|
+
ref as ref38
|
|
5168
|
+
} from "@vue/runtime-core";
|
|
5169
|
+
function createTheme(definition) {
|
|
5170
|
+
const key = /* @__PURE__ */ Symbol("vue-native-theme");
|
|
5171
|
+
const ThemeProvider = defineComponent35({
|
|
5172
|
+
name: "ThemeProvider",
|
|
5173
|
+
props: {
|
|
5174
|
+
initialColorScheme: {
|
|
5175
|
+
type: String,
|
|
5176
|
+
default: "light"
|
|
5177
|
+
}
|
|
5178
|
+
},
|
|
5179
|
+
setup(props, { slots }) {
|
|
5180
|
+
const colorScheme = ref38(props.initialColorScheme);
|
|
5181
|
+
const theme = computed3(() => {
|
|
5182
|
+
return colorScheme.value === "dark" ? definition.dark : definition.light;
|
|
5183
|
+
});
|
|
5184
|
+
const ctx = {
|
|
5185
|
+
theme,
|
|
5186
|
+
colorScheme,
|
|
5187
|
+
toggleColorScheme: () => {
|
|
5188
|
+
colorScheme.value = colorScheme.value === "light" ? "dark" : "light";
|
|
5189
|
+
},
|
|
5190
|
+
setColorScheme: (scheme) => {
|
|
5191
|
+
colorScheme.value = scheme;
|
|
5192
|
+
}
|
|
5193
|
+
};
|
|
5194
|
+
provide3(key, ctx);
|
|
5195
|
+
return () => slots.default?.();
|
|
5196
|
+
}
|
|
5197
|
+
});
|
|
5198
|
+
function useTheme() {
|
|
5199
|
+
const ctx = inject3(key);
|
|
5200
|
+
if (!ctx) {
|
|
5201
|
+
throw new Error(
|
|
5202
|
+
"[Vue Native] useTheme() was called outside of a <ThemeProvider>. Wrap your app root with <ThemeProvider> to provide theme context."
|
|
5203
|
+
);
|
|
5204
|
+
}
|
|
5205
|
+
return ctx;
|
|
5206
|
+
}
|
|
5207
|
+
return { ThemeProvider, useTheme };
|
|
5208
|
+
}
|
|
5209
|
+
function createDynamicStyleSheet(theme, factory) {
|
|
5210
|
+
return computed3(() => createStyleSheet(factory(theme.value)));
|
|
5211
|
+
}
|
|
5212
|
+
|
|
3476
5213
|
// src/index.ts
|
|
3477
5214
|
function createApp(rootComponent, rootProps) {
|
|
3478
5215
|
const app = baseCreateApp(rootComponent, rootProps);
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
app.component("
|
|
3483
|
-
app.component("
|
|
3484
|
-
app.component("VActivityIndicator", VActivityIndicator);
|
|
3485
|
-
app.component("VScrollView", VScrollView);
|
|
3486
|
-
app.component("VImage", VImage);
|
|
3487
|
-
app.component("VKeyboardAvoiding", VKeyboardAvoiding);
|
|
3488
|
-
app.component("VSafeArea", VSafeArea);
|
|
3489
|
-
app.component("VSlider", VSlider);
|
|
3490
|
-
app.component("VList", VList);
|
|
3491
|
-
app.component("VModal", VModal);
|
|
3492
|
-
app.component("VAlertDialog", VAlertDialog);
|
|
3493
|
-
app.component("VStatusBar", VStatusBar);
|
|
3494
|
-
app.component("VWebView", VWebView);
|
|
3495
|
-
app.component("VProgressBar", VProgressBar);
|
|
3496
|
-
app.component("VPicker", VPicker);
|
|
3497
|
-
app.component("VSegmentedControl", VSegmentedControl);
|
|
3498
|
-
app.component("VActionSheet", VActionSheet);
|
|
3499
|
-
app.component("VRefreshControl", VRefreshControl);
|
|
3500
|
-
app.component("VPressable", VPressable);
|
|
3501
|
-
app.component("VSectionList", VSectionList);
|
|
3502
|
-
app.component("VCheckbox", VCheckbox);
|
|
3503
|
-
app.component("VRadio", VRadio);
|
|
3504
|
-
app.component("VDropdown", VDropdown);
|
|
3505
|
-
app.component("VVideo", VVideo);
|
|
5216
|
+
for (const [name, component] of Object.entries(builtInComponents)) {
|
|
5217
|
+
app.component(name, component);
|
|
5218
|
+
}
|
|
5219
|
+
app.component("VDrawer.Item", VDrawerItem);
|
|
5220
|
+
app.component("VDrawer.Section", VDrawerSection);
|
|
3506
5221
|
app.component("ErrorBoundary", ErrorBoundary);
|
|
3507
5222
|
app.component("VErrorBoundary", ErrorBoundary);
|
|
3508
|
-
app.directive("show", vShow);
|
|
3509
5223
|
app.config.errorHandler = (err, instance, info) => {
|
|
3510
5224
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
3511
5225
|
const componentName = instance?.$options?.name || instance?.$.type?.name || "Anonymous";
|
|
@@ -3546,7 +5260,11 @@ export {
|
|
|
3546
5260
|
VAlertDialog,
|
|
3547
5261
|
VButton,
|
|
3548
5262
|
VCheckbox,
|
|
5263
|
+
VDrawer,
|
|
5264
|
+
VDrawerItem,
|
|
5265
|
+
VDrawerSection,
|
|
3549
5266
|
VDropdown,
|
|
5267
|
+
VFlatList,
|
|
3550
5268
|
VImage,
|
|
3551
5269
|
VInput,
|
|
3552
5270
|
VKeyboardAvoiding,
|
|
@@ -3564,16 +5282,20 @@ export {
|
|
|
3564
5282
|
VSlider,
|
|
3565
5283
|
VStatusBar,
|
|
3566
5284
|
VSwitch,
|
|
5285
|
+
VTabBar,
|
|
3567
5286
|
VText,
|
|
3568
5287
|
VVideo,
|
|
3569
5288
|
VView,
|
|
3570
5289
|
VWebView,
|
|
5290
|
+
builtInComponents,
|
|
3571
5291
|
clearSharedElementRegistry,
|
|
3572
5292
|
createApp,
|
|
3573
5293
|
createCommentNode,
|
|
5294
|
+
createDynamicStyleSheet,
|
|
3574
5295
|
createNativeNode,
|
|
3575
5296
|
createStyleSheet,
|
|
3576
5297
|
createTextNode,
|
|
5298
|
+
createTheme,
|
|
3577
5299
|
getRegisteredSharedElements,
|
|
3578
5300
|
getSharedElementViewId,
|
|
3579
5301
|
measureViewFrame,
|
|
@@ -3593,12 +5315,16 @@ export {
|
|
|
3593
5315
|
useCamera,
|
|
3594
5316
|
useClipboard,
|
|
3595
5317
|
useColorScheme,
|
|
5318
|
+
useComposedGestures,
|
|
3596
5319
|
useContacts,
|
|
3597
5320
|
useDatabase,
|
|
3598
5321
|
useDeviceInfo,
|
|
3599
5322
|
useDimensions,
|
|
5323
|
+
useDragDrop,
|
|
5324
|
+
useFileDialog,
|
|
3600
5325
|
useFileSystem,
|
|
3601
5326
|
useGeolocation,
|
|
5327
|
+
useGesture,
|
|
3602
5328
|
useGoogleSignIn,
|
|
3603
5329
|
useGyroscope,
|
|
3604
5330
|
useHaptics,
|
|
@@ -3607,6 +5333,7 @@ export {
|
|
|
3607
5333
|
useIAP,
|
|
3608
5334
|
useKeyboard,
|
|
3609
5335
|
useLinking,
|
|
5336
|
+
useMenu,
|
|
3610
5337
|
useNetwork,
|
|
3611
5338
|
useNotifications,
|
|
3612
5339
|
useOTAUpdate,
|
|
@@ -3616,7 +5343,10 @@ export {
|
|
|
3616
5343
|
useSecureStorage,
|
|
3617
5344
|
useShare,
|
|
3618
5345
|
useSharedElementTransition,
|
|
5346
|
+
useTeleport,
|
|
3619
5347
|
useWebSocket,
|
|
5348
|
+
useWindow,
|
|
5349
|
+
vModel,
|
|
3620
5350
|
vShow,
|
|
3621
5351
|
validStyleProperties
|
|
3622
5352
|
};
|