@wireai/activation 0.13.0 → 0.13.3
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/AGENTS.md +7 -4
- package/CHANGELOG.md +341 -4
- package/README.md +98 -2
- package/dist/analytics/index.d.mts +4 -4
- package/dist/analytics/index.d.ts +4 -4
- package/dist/analytics/index.js +164 -471
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +162 -469
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/coachmarks/index.d.mts +14 -1
- package/dist/coachmarks/index.d.ts +14 -1
- package/dist/coachmarks/index.js +58 -14
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs +58 -14
- package/dist/coachmarks/index.mjs.map +1 -1
- package/dist/{currentSession-_GynvhzT.d.mts → currentSession-BoWtr3Jp.d.mts} +299 -14
- package/dist/{currentSession-D7zabMXK.d.ts → currentSession-CCOMlaQ2.d.ts} +299 -14
- package/dist/{decision-Bl_M2y3r.d.mts → decision-Cjw0jbEj.d.mts} +1 -1
- package/dist/{decision-Cau5KmP6.d.ts → decision-GfpXAsk_.d.ts} +1 -1
- package/dist/index.d.mts +218 -4
- package/dist/index.d.ts +218 -4
- package/dist/index.js +1104 -888
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +887 -692
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.d.mts +42 -10
- package/dist/questionnaire/index.d.ts +42 -10
- package/dist/questionnaire/index.js +45 -13
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs +45 -13
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.d.mts +4 -4
- package/dist/reviews/index.d.ts +4 -4
- package/dist/reviews/index.js +39 -8
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs +39 -8
- package/dist/reviews/index.mjs.map +1 -1
- package/dist/showcase/index.js +7 -2
- package/dist/showcase/index.js.map +1 -1
- package/dist/showcase/index.mjs +7 -2
- package/dist/showcase/index.mjs.map +1 -1
- package/dist/{transport-DsRe4epC.d.ts → transport-CefdERPs.d.mts} +44 -5
- package/dist/{transport-CF_eHwzC.d.mts → transport-DFuPyCoJ.d.ts} +44 -5
- package/dist/{types-Buj9Lw9t.d.ts → types-UVYt9BJe.d.ts} +41 -1
- package/dist/{types-CNUqMK0D.d.mts → types-l2tfg23P.d.mts} +41 -1
- package/package.json +4 -1
- package/src/OnboardingFlow.tsx +175 -15
- package/src/WireOnboarding.tsx +70 -8
- package/src/activation/wireActivation.ts +3 -3
- package/src/analytics/analyticsEvent.ts +16 -1
- package/src/analytics/analyticsFacade.ts +2 -2
- package/src/analytics/eventQueue.ts +85 -20
- package/src/analytics/reportClientEvent.ts +68 -12
- package/src/cards/CardGridSelectCard.tsx +1 -1
- package/src/cards/ChipSelectCard.tsx +2 -2
- package/src/cards/PermissionCard.tsx +438 -0
- package/src/cards/SelectionCard.tsx +1 -1
- package/src/cards/index.ts +7 -0
- package/src/coachmarks/runtime.ts +62 -2
- package/src/coachmarks/useCoachmarkTour.ts +62 -14
- package/src/context/deviceId.ts +4 -4
- package/src/features/WireFeaturesProvider.tsx +4 -1
- package/src/identity/userIdentity.ts +1 -1
- package/src/illustrations/defaultIllustrations.tsx +44 -3
- package/src/index.ts +38 -0
- package/src/permissions/index.ts +64 -0
- package/src/permissions/permissionCopy.ts +87 -0
- package/src/permissions/permissionEvents.ts +76 -0
- package/src/permissions/permissionMemory.ts +88 -0
- package/src/permissions/placement.ts +88 -0
- package/src/permissions/types.ts +131 -0
- package/src/questionnaire/QuestionnaireGate.tsx +90 -10
- package/src/questionnaire/index.ts +9 -1
- package/src/questionnaire/transport.ts +46 -11
- package/src/reviews/ReviewGate.tsx +61 -6
- package/src/reviews/index.ts +10 -1
- package/src/reviews/transport.ts +58 -12
- package/src/session/persistedSession.ts +10 -3
- package/src/session-analytics/useLifecycleEvents.ts +1 -1
- package/src/theme/ThemeContext.tsx +42 -1
- package/src/types.ts +66 -4
- package/src/utils/submitResult.ts +39 -0
package/dist/index.js
CHANGED
|
@@ -1,412 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var React18 = require('react');
|
|
3
|
+
var React19 = require('react');
|
|
5
4
|
var wireaiRn = require('wireai-rn');
|
|
6
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var reactNative = require('react-native');
|
|
7
7
|
var reactNativeSafeAreaContext = require('react-native-safe-area-context');
|
|
8
8
|
var zod = require('zod');
|
|
9
9
|
|
|
10
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var React19__default = /*#__PURE__*/_interopDefault(React19);
|
|
13
13
|
|
|
14
14
|
var __defProp = Object.defineProperty;
|
|
15
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
16
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
17
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
18
15
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
19
16
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
20
17
|
}) : x)(function(x) {
|
|
21
18
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
22
19
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
23
20
|
});
|
|
24
|
-
var __esm = (fn, res) => function __init() {
|
|
25
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
26
|
-
};
|
|
27
21
|
var __export = (target, all) => {
|
|
28
|
-
for (var
|
|
29
|
-
__defProp(target,
|
|
30
|
-
};
|
|
31
|
-
var __copyProps = (to, from, except, desc) => {
|
|
32
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
33
|
-
for (let key of __getOwnPropNames(from))
|
|
34
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
35
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
36
|
-
}
|
|
37
|
-
return to;
|
|
22
|
+
for (var name in all)
|
|
23
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
38
24
|
};
|
|
39
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
40
|
-
|
|
41
|
-
// node_modules/expo-modules-core/src/errors/CodedError.ts
|
|
42
|
-
var CodedError;
|
|
43
|
-
var init_CodedError = __esm({
|
|
44
|
-
"node_modules/expo-modules-core/src/errors/CodedError.ts"() {
|
|
45
|
-
CodedError = class extends Error {
|
|
46
|
-
constructor(code, message) {
|
|
47
|
-
super(message);
|
|
48
|
-
this.code = code;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// node_modules/expo-modules-core/src/NativeModulesProxy.ts
|
|
55
|
-
var NativeModulesProxy_default;
|
|
56
|
-
var init_NativeModulesProxy = __esm({
|
|
57
|
-
"node_modules/expo-modules-core/src/NativeModulesProxy.ts"() {
|
|
58
|
-
NativeModulesProxy_default = {};
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// node_modules/expo-modules-core/src/TurboModuleToExpoModuleProxy.ts
|
|
63
|
-
function createTurboModuleToExpoProxy(turboModule, name2) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
var init_TurboModuleToExpoModuleProxy = __esm({
|
|
67
|
-
"node_modules/expo-modules-core/src/TurboModuleToExpoModuleProxy.ts"() {
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
var init_ensureNativeModulesAreInstalled = __esm({
|
|
71
|
-
"node_modules/expo-modules-core/src/ensureNativeModulesAreInstalled.ts"() {
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
function requireOptionalNativeModule(moduleName) {
|
|
75
|
-
var _a2, _b, _c, _d, _e;
|
|
76
|
-
try {
|
|
77
|
-
return (_e = (_d = (_c = (_b = (_a2 = globalThis.expo) == null ? void 0 : _a2.modules) == null ? void 0 : _b[moduleName]) != null ? _c : NativeModulesProxy_default[moduleName]) != null ? _d : createTurboModuleToExpoProxy(reactNative.TurboModuleRegistry.get(moduleName), moduleName)) != null ? _e : null;
|
|
78
|
-
} catch (e) {
|
|
79
|
-
const error = e;
|
|
80
|
-
console.warn(`An error occurred while requiring the '${moduleName}' module: ${error.message}`);
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
var init_requireNativeModule = __esm({
|
|
85
|
-
"node_modules/expo-modules-core/src/requireNativeModule.ts"() {
|
|
86
|
-
init_NativeModulesProxy();
|
|
87
|
-
init_TurboModuleToExpoModuleProxy();
|
|
88
|
-
init_ensureNativeModulesAreInstalled();
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// node_modules/expo-modules-core/src/sweet/setUpJsLogger.fx.ts
|
|
93
|
-
var init_setUpJsLogger_fx = __esm({
|
|
94
|
-
"node_modules/expo-modules-core/src/sweet/setUpJsLogger.fx.ts"() {
|
|
95
|
-
init_CodedError();
|
|
96
|
-
init_requireNativeModule();
|
|
97
|
-
if (__DEV__ && typeof window !== "undefined" && (process.env.EXPO_OS === "android" || process.env.EXPO_OS === "ios")) {
|
|
98
|
-
const NativeJSLogger = requireOptionalNativeModule("ExpoModulesCoreJSLogger");
|
|
99
|
-
if (NativeJSLogger) {
|
|
100
|
-
const onNewException = {
|
|
101
|
-
eventName: "ExpoModulesCoreJSLogger.onNewError",
|
|
102
|
-
action: console.error
|
|
103
|
-
};
|
|
104
|
-
const onNewWarning = {
|
|
105
|
-
eventName: "ExpoModulesCoreJSLogger.onNewWarning",
|
|
106
|
-
action: console.warn
|
|
107
|
-
};
|
|
108
|
-
const onNewDebug = {
|
|
109
|
-
eventName: "ExpoModulesCoreJSLogger.onNewDebug",
|
|
110
|
-
action: console.debug
|
|
111
|
-
};
|
|
112
|
-
const onNewInfo = {
|
|
113
|
-
eventName: "ExpoModulesCoreJSLogger.onNewInfo",
|
|
114
|
-
action: console.info
|
|
115
|
-
};
|
|
116
|
-
const onNewTrace = {
|
|
117
|
-
eventName: "ExpoModulesCoreJSLogger.onNewTrace",
|
|
118
|
-
action: console.trace
|
|
119
|
-
};
|
|
120
|
-
const listeners = [
|
|
121
|
-
onNewException,
|
|
122
|
-
onNewWarning,
|
|
123
|
-
onNewDebug,
|
|
124
|
-
onNewInfo,
|
|
125
|
-
onNewTrace
|
|
126
|
-
];
|
|
127
|
-
for (const listener of listeners) {
|
|
128
|
-
NativeJSLogger.addListener(listener.eventName, ({ message }) => {
|
|
129
|
-
listener.action(message);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
globalThis.ExpoModulesCore_CodedError = CodedError;
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// node_modules/expo-modules-core/src/registerWebModule.ts
|
|
139
|
-
var init_registerWebModule = __esm({
|
|
140
|
-
"node_modules/expo-modules-core/src/registerWebModule.ts"() {
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
// node_modules/expo-modules-core/src/TypedArrays.types.ts
|
|
145
|
-
var init_TypedArrays_types = __esm({
|
|
146
|
-
"node_modules/expo-modules-core/src/TypedArrays.types.ts"() {
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
// node_modules/expo-modules-core/src/PermissionsInterface.ts
|
|
151
|
-
var init_PermissionsInterface = __esm({
|
|
152
|
-
"node_modules/expo-modules-core/src/PermissionsInterface.ts"() {
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
var init_PermissionsHook = __esm({
|
|
156
|
-
"node_modules/expo-modules-core/src/PermissionsHook.ts"() {
|
|
157
|
-
"use client";
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
var init_Refs = __esm({
|
|
161
|
-
"node_modules/expo-modules-core/src/Refs.ts"() {
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
var init_useReleasingSharedObject = __esm({
|
|
165
|
-
"node_modules/expo-modules-core/src/hooks/useReleasingSharedObject.ts"() {
|
|
166
|
-
"use client";
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// node_modules/expo-modules-core/src/reload.ts
|
|
171
|
-
var init_reload = __esm({
|
|
172
|
-
"node_modules/expo-modules-core/src/reload.ts"() {
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
// node_modules/expo-modules-core/src/index.ts
|
|
177
|
-
var init_src = __esm({
|
|
178
|
-
"node_modules/expo-modules-core/src/index.ts"() {
|
|
179
|
-
init_setUpJsLogger_fx();
|
|
180
|
-
init_requireNativeModule();
|
|
181
|
-
init_registerWebModule();
|
|
182
|
-
init_TypedArrays_types();
|
|
183
|
-
init_PermissionsInterface();
|
|
184
|
-
init_PermissionsHook();
|
|
185
|
-
init_Refs();
|
|
186
|
-
init_useReleasingSharedObject();
|
|
187
|
-
init_reload();
|
|
188
|
-
init_CodedError();
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// node_modules/expo-constants/build/Constants.types.js
|
|
193
|
-
var AppOwnership, ExecutionEnvironment, UserInterfaceIdiom;
|
|
194
|
-
var init_Constants_types = __esm({
|
|
195
|
-
"node_modules/expo-constants/build/Constants.types.js"() {
|
|
196
|
-
(function(AppOwnership2) {
|
|
197
|
-
AppOwnership2["Expo"] = "expo";
|
|
198
|
-
})(AppOwnership || (AppOwnership = {}));
|
|
199
|
-
(function(ExecutionEnvironment2) {
|
|
200
|
-
ExecutionEnvironment2["Bare"] = "bare";
|
|
201
|
-
ExecutionEnvironment2["Standalone"] = "standalone";
|
|
202
|
-
ExecutionEnvironment2["StoreClient"] = "storeClient";
|
|
203
|
-
})(ExecutionEnvironment || (ExecutionEnvironment = {}));
|
|
204
|
-
(function(UserInterfaceIdiom2) {
|
|
205
|
-
UserInterfaceIdiom2["Handset"] = "handset";
|
|
206
|
-
UserInterfaceIdiom2["Tablet"] = "tablet";
|
|
207
|
-
UserInterfaceIdiom2["Desktop"] = "desktop";
|
|
208
|
-
UserInterfaceIdiom2["TV"] = "tv";
|
|
209
|
-
UserInterfaceIdiom2["Unsupported"] = "unsupported";
|
|
210
|
-
})(UserInterfaceIdiom || (UserInterfaceIdiom = {}));
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
// node_modules/expo-constants/build/ExponentConstants.js
|
|
215
|
-
var ExponentConstants_default;
|
|
216
|
-
var init_ExponentConstants = __esm({
|
|
217
|
-
"node_modules/expo-constants/build/ExponentConstants.js"() {
|
|
218
|
-
init_src();
|
|
219
|
-
ExponentConstants_default = requireOptionalNativeModule("ExponentConstants");
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
// node_modules/expo-constants/build/Constants.js
|
|
224
|
-
var Constants_exports = {};
|
|
225
|
-
__export(Constants_exports, {
|
|
226
|
-
AppOwnership: () => AppOwnership,
|
|
227
|
-
ExecutionEnvironment: () => ExecutionEnvironment,
|
|
228
|
-
UserInterfaceIdiom: () => UserInterfaceIdiom,
|
|
229
|
-
default: () => Constants_default
|
|
230
|
-
});
|
|
231
|
-
function isEmbeddedManifest(manifest) {
|
|
232
|
-
return !isExpoUpdatesManifest(manifest);
|
|
233
|
-
}
|
|
234
|
-
function isExpoUpdatesManifest(manifest) {
|
|
235
|
-
return "metadata" in manifest;
|
|
236
|
-
}
|
|
237
|
-
function getManifest(suppressWarning = false) {
|
|
238
|
-
if (!rawManifest) {
|
|
239
|
-
const invalidManifestType = rawManifest === null ? "null" : "undefined";
|
|
240
|
-
if (nativeConstants.executionEnvironment === ExecutionEnvironment.Bare && reactNative.Platform.OS !== "web") {
|
|
241
|
-
if (!suppressWarning) {
|
|
242
|
-
console.warn(`Constants.manifest is ${invalidManifestType} because the embedded app.config could not be read. Ensure that you have installed the expo-constants build scripts if you need to read from Constants.manifest.`);
|
|
243
|
-
}
|
|
244
|
-
} else if (nativeConstants.executionEnvironment === ExecutionEnvironment.StoreClient || nativeConstants.executionEnvironment === ExecutionEnvironment.Standalone) {
|
|
245
|
-
throw new CodedError("ERR_CONSTANTS_MANIFEST_UNAVAILABLE", `Constants.manifest is ${invalidManifestType}, must be an object.`);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return rawManifest;
|
|
249
|
-
}
|
|
250
|
-
var ExpoUpdates, rawUpdatesManifest, rawDevLauncherManifest, rawAppConfig, _a, rawManifest, name, appOwnership, nativeConstants, constants, Constants_default;
|
|
251
|
-
var init_Constants = __esm({
|
|
252
|
-
"node_modules/expo-constants/build/Constants.js"() {
|
|
253
|
-
init_src();
|
|
254
|
-
init_Constants_types();
|
|
255
|
-
init_ExponentConstants();
|
|
256
|
-
init_Constants_types();
|
|
257
|
-
if (!ExponentConstants_default) {
|
|
258
|
-
console.warn("No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?");
|
|
259
|
-
}
|
|
260
|
-
ExpoUpdates = requireOptionalNativeModule("ExpoUpdates");
|
|
261
|
-
rawUpdatesManifest = null;
|
|
262
|
-
if (ExpoUpdates) {
|
|
263
|
-
let updatesManifest;
|
|
264
|
-
if (ExpoUpdates.manifest) {
|
|
265
|
-
updatesManifest = ExpoUpdates.manifest;
|
|
266
|
-
} else if (ExpoUpdates.manifestString) {
|
|
267
|
-
updatesManifest = JSON.parse(ExpoUpdates.manifestString);
|
|
268
|
-
}
|
|
269
|
-
if (updatesManifest && Object.keys(updatesManifest).length > 0) {
|
|
270
|
-
rawUpdatesManifest = updatesManifest;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
rawDevLauncherManifest = null;
|
|
274
|
-
if (reactNative.NativeModules.EXDevLauncher) {
|
|
275
|
-
let devLauncherManifest;
|
|
276
|
-
if (reactNative.NativeModules.EXDevLauncher.manifestString) {
|
|
277
|
-
devLauncherManifest = JSON.parse(reactNative.NativeModules.EXDevLauncher.manifestString);
|
|
278
|
-
}
|
|
279
|
-
if (devLauncherManifest && Object.keys(devLauncherManifest).length > 0) {
|
|
280
|
-
rawDevLauncherManifest = devLauncherManifest;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
rawAppConfig = null;
|
|
284
|
-
if (ExponentConstants_default && ExponentConstants_default.manifest) {
|
|
285
|
-
const appConfig = ExponentConstants_default.manifest;
|
|
286
|
-
if (typeof appConfig === "string") {
|
|
287
|
-
rawAppConfig = JSON.parse(appConfig);
|
|
288
|
-
} else {
|
|
289
|
-
rawAppConfig = appConfig;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
rawManifest = (_a = rawUpdatesManifest != null ? rawUpdatesManifest : rawDevLauncherManifest) != null ? _a : rawAppConfig;
|
|
293
|
-
({ name, appOwnership, ...nativeConstants } = ExponentConstants_default || {});
|
|
294
|
-
constants = {
|
|
295
|
-
...nativeConstants,
|
|
296
|
-
// Ensure this is null in bare workflow
|
|
297
|
-
appOwnership: appOwnership != null ? appOwnership : null
|
|
298
|
-
};
|
|
299
|
-
Object.defineProperties(constants, {
|
|
300
|
-
/**
|
|
301
|
-
* Use `manifest` property by default.
|
|
302
|
-
* This property is only used for internal purposes.
|
|
303
|
-
* It behaves similarly to the original one, but suppresses warning upon no manifest available.
|
|
304
|
-
* `expo-asset` uses it to prevent users from seeing mentioned warning.
|
|
305
|
-
*/
|
|
306
|
-
__unsafeNoWarnManifest: {
|
|
307
|
-
get() {
|
|
308
|
-
const maybeManifest = getManifest(true);
|
|
309
|
-
if (!maybeManifest || !isEmbeddedManifest(maybeManifest)) {
|
|
310
|
-
return null;
|
|
311
|
-
}
|
|
312
|
-
return maybeManifest;
|
|
313
|
-
},
|
|
314
|
-
enumerable: false
|
|
315
|
-
},
|
|
316
|
-
__unsafeNoWarnManifest2: {
|
|
317
|
-
get() {
|
|
318
|
-
const maybeManifest = getManifest(true);
|
|
319
|
-
if (!maybeManifest || !isExpoUpdatesManifest(maybeManifest)) {
|
|
320
|
-
return null;
|
|
321
|
-
}
|
|
322
|
-
return maybeManifest;
|
|
323
|
-
},
|
|
324
|
-
enumerable: false
|
|
325
|
-
},
|
|
326
|
-
manifest: {
|
|
327
|
-
get() {
|
|
328
|
-
const maybeManifest = getManifest();
|
|
329
|
-
if (!maybeManifest || !isEmbeddedManifest(maybeManifest)) {
|
|
330
|
-
return null;
|
|
331
|
-
}
|
|
332
|
-
return maybeManifest;
|
|
333
|
-
},
|
|
334
|
-
enumerable: true
|
|
335
|
-
},
|
|
336
|
-
manifest2: {
|
|
337
|
-
get() {
|
|
338
|
-
const maybeManifest = getManifest();
|
|
339
|
-
if (!maybeManifest || !isExpoUpdatesManifest(maybeManifest)) {
|
|
340
|
-
return null;
|
|
341
|
-
}
|
|
342
|
-
return maybeManifest;
|
|
343
|
-
},
|
|
344
|
-
enumerable: true
|
|
345
|
-
},
|
|
346
|
-
expoConfig: {
|
|
347
|
-
get() {
|
|
348
|
-
var _a2, _b;
|
|
349
|
-
const maybeManifest = getManifest(true);
|
|
350
|
-
if (!maybeManifest) {
|
|
351
|
-
return null;
|
|
352
|
-
}
|
|
353
|
-
if (ExpoUpdates && ExpoUpdates.isEmbeddedLaunch) {
|
|
354
|
-
return rawAppConfig;
|
|
355
|
-
}
|
|
356
|
-
if (isExpoUpdatesManifest(maybeManifest)) {
|
|
357
|
-
return (_b = (_a2 = maybeManifest.extra) == null ? void 0 : _a2.expoClient) != null ? _b : null;
|
|
358
|
-
} else if (isEmbeddedManifest(maybeManifest)) {
|
|
359
|
-
return maybeManifest;
|
|
360
|
-
}
|
|
361
|
-
return null;
|
|
362
|
-
},
|
|
363
|
-
enumerable: true
|
|
364
|
-
},
|
|
365
|
-
expoGoConfig: {
|
|
366
|
-
get() {
|
|
367
|
-
var _a2, _b;
|
|
368
|
-
const maybeManifest = getManifest(true);
|
|
369
|
-
if (!maybeManifest) {
|
|
370
|
-
return null;
|
|
371
|
-
}
|
|
372
|
-
if (isExpoUpdatesManifest(maybeManifest)) {
|
|
373
|
-
return (_b = (_a2 = maybeManifest.extra) == null ? void 0 : _a2.expoGo) != null ? _b : null;
|
|
374
|
-
} else if (isEmbeddedManifest(maybeManifest)) {
|
|
375
|
-
return maybeManifest;
|
|
376
|
-
}
|
|
377
|
-
return null;
|
|
378
|
-
},
|
|
379
|
-
enumerable: true
|
|
380
|
-
},
|
|
381
|
-
easConfig: {
|
|
382
|
-
get() {
|
|
383
|
-
var _a2, _b;
|
|
384
|
-
const maybeManifest = getManifest(true);
|
|
385
|
-
if (!maybeManifest) {
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
if (isExpoUpdatesManifest(maybeManifest)) {
|
|
389
|
-
return (_b = (_a2 = maybeManifest.extra) == null ? void 0 : _a2.eas) != null ? _b : null;
|
|
390
|
-
} else if (isEmbeddedManifest(maybeManifest)) {
|
|
391
|
-
return maybeManifest;
|
|
392
|
-
}
|
|
393
|
-
return null;
|
|
394
|
-
},
|
|
395
|
-
enumerable: true
|
|
396
|
-
},
|
|
397
|
-
__rawManifest_TEST: {
|
|
398
|
-
get() {
|
|
399
|
-
return rawManifest;
|
|
400
|
-
},
|
|
401
|
-
set(value) {
|
|
402
|
-
rawManifest = value;
|
|
403
|
-
},
|
|
404
|
-
enumerable: false
|
|
405
|
-
}
|
|
406
|
-
});
|
|
407
|
-
Constants_default = constants;
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
25
|
|
|
411
26
|
// src/theme/defaultTheme.ts
|
|
412
27
|
var defaultOnboardingTheme = {
|
|
@@ -464,33 +79,38 @@ var mergeTheme = (override) => {
|
|
|
464
79
|
button: { ...defaultOnboardingTheme.button, ...override.button }
|
|
465
80
|
};
|
|
466
81
|
};
|
|
467
|
-
var
|
|
82
|
+
var THEME_CONTEXT_SLOT = /* @__PURE__ */ Symbol.for("@wireai/activation:themeContext");
|
|
83
|
+
var themeGlobal = globalThis;
|
|
84
|
+
if (!themeGlobal[THEME_CONTEXT_SLOT]) {
|
|
85
|
+
themeGlobal[THEME_CONTEXT_SLOT] = React19.createContext(null);
|
|
86
|
+
}
|
|
87
|
+
var OnboardingThemeContext = themeGlobal[THEME_CONTEXT_SLOT];
|
|
468
88
|
var OnboardingThemeProvider = ({
|
|
469
89
|
theme,
|
|
470
90
|
children
|
|
471
91
|
}) => {
|
|
472
|
-
const resolved =
|
|
92
|
+
const resolved = React19.useMemo(() => mergeTheme(theme), [theme]);
|
|
473
93
|
return /* @__PURE__ */ jsxRuntime.jsx(OnboardingThemeContext.Provider, { value: resolved, children });
|
|
474
94
|
};
|
|
475
95
|
var useOnboardingTheme = () => {
|
|
476
|
-
const ctx =
|
|
96
|
+
const ctx = React19.useContext(OnboardingThemeContext);
|
|
477
97
|
return ctx != null ? ctx : mergeTheme();
|
|
478
98
|
};
|
|
479
99
|
var EMPTY_REGISTRY = {};
|
|
480
|
-
var IllustrationContext =
|
|
100
|
+
var IllustrationContext = React19.createContext(EMPTY_REGISTRY);
|
|
481
101
|
var IllustrationProvider = ({
|
|
482
102
|
registry,
|
|
483
103
|
children
|
|
484
104
|
}) => {
|
|
485
|
-
const value =
|
|
105
|
+
const value = React19.useMemo(() => registry != null ? registry : EMPTY_REGISTRY, [registry]);
|
|
486
106
|
return /* @__PURE__ */ jsxRuntime.jsx(IllustrationContext.Provider, { value, children });
|
|
487
107
|
};
|
|
488
|
-
var useIllustration = (
|
|
489
|
-
const registry =
|
|
490
|
-
if (!
|
|
491
|
-
return registry[
|
|
108
|
+
var useIllustration = (name) => {
|
|
109
|
+
const registry = React19.useContext(IllustrationContext);
|
|
110
|
+
if (!name) return void 0;
|
|
111
|
+
return registry[name];
|
|
492
112
|
};
|
|
493
|
-
var
|
|
113
|
+
var Disc = ({ children }) => {
|
|
494
114
|
const t = useOnboardingTheme();
|
|
495
115
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
496
116
|
reactNative.View,
|
|
@@ -499,11 +119,23 @@ var Glyph = ({ children }) => {
|
|
|
499
119
|
styles.disc,
|
|
500
120
|
{ backgroundColor: t.colors.primarySoft, borderRadius: t.radius.full }
|
|
501
121
|
],
|
|
502
|
-
children
|
|
122
|
+
children
|
|
503
123
|
}
|
|
504
124
|
);
|
|
505
125
|
};
|
|
126
|
+
var Glyph = ({ children }) => {
|
|
127
|
+
const t = useOnboardingTheme();
|
|
128
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Disc, { children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.glyphText, { color: t.colors.primary }], allowFontScaling: false, children }) });
|
|
129
|
+
};
|
|
506
130
|
var MomentumGlyph = () => /* @__PURE__ */ jsxRuntime.jsx(Glyph, { children: "\u2197" });
|
|
131
|
+
var NotificationsGlyph = () => {
|
|
132
|
+
const t = useOnboardingTheme();
|
|
133
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Disc, { children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.bell, children: [
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.bellBody, { backgroundColor: t.colors.primary }] }),
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.bellRim, { backgroundColor: t.colors.primary }] }),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.bellClapper, { backgroundColor: t.colors.primary }] })
|
|
137
|
+
] }) });
|
|
138
|
+
};
|
|
507
139
|
var BeforeAfterGlyph = () => {
|
|
508
140
|
const t = useOnboardingTheme();
|
|
509
141
|
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.row, children: [
|
|
@@ -530,7 +162,8 @@ var BeforeAfterGlyph = () => {
|
|
|
530
162
|
};
|
|
531
163
|
var defaultIllustrations = {
|
|
532
164
|
momentum: /* @__PURE__ */ jsxRuntime.jsx(MomentumGlyph, {}),
|
|
533
|
-
"before-after": /* @__PURE__ */ jsxRuntime.jsx(BeforeAfterGlyph, {})
|
|
165
|
+
"before-after": /* @__PURE__ */ jsxRuntime.jsx(BeforeAfterGlyph, {}),
|
|
166
|
+
notifications: /* @__PURE__ */ jsxRuntime.jsx(NotificationsGlyph, {})
|
|
534
167
|
};
|
|
535
168
|
var styles = reactNative.StyleSheet.create({
|
|
536
169
|
disc: {
|
|
@@ -558,22 +191,27 @@ var styles = reactNative.StyleSheet.create({
|
|
|
558
191
|
arrow: {
|
|
559
192
|
fontSize: 28,
|
|
560
193
|
fontWeight: "700"
|
|
561
|
-
}
|
|
194
|
+
},
|
|
195
|
+
// The bell: a domed body over a wider rim, with the clapper hanging below it.
|
|
196
|
+
bell: { alignItems: "center", justifyContent: "center" },
|
|
197
|
+
bellBody: { width: 34, height: 30, borderTopLeftRadius: 17, borderTopRightRadius: 17 },
|
|
198
|
+
bellRim: { width: 44, height: 5, borderRadius: 3, marginTop: 2 },
|
|
199
|
+
bellClapper: { width: 9, height: 9, borderRadius: 5, marginTop: 3 }
|
|
562
200
|
});
|
|
563
201
|
var EMPTY_REGISTRY2 = {};
|
|
564
|
-
var IconContext =
|
|
202
|
+
var IconContext = React19.createContext(EMPTY_REGISTRY2);
|
|
565
203
|
var IconRegistryProvider = ({
|
|
566
204
|
registry,
|
|
567
205
|
children
|
|
568
206
|
}) => {
|
|
569
|
-
const value =
|
|
207
|
+
const value = React19.useMemo(() => registry != null ? registry : EMPTY_REGISTRY2, [registry]);
|
|
570
208
|
return /* @__PURE__ */ jsxRuntime.jsx(IconContext.Provider, { value, children });
|
|
571
209
|
};
|
|
572
|
-
var useHostIcon = (
|
|
573
|
-
const registry =
|
|
574
|
-
if (!
|
|
575
|
-
if (!Object.prototype.hasOwnProperty.call(registry,
|
|
576
|
-
return registry[
|
|
210
|
+
var useHostIcon = (name) => {
|
|
211
|
+
const registry = React19.useContext(IconContext);
|
|
212
|
+
if (!name) return void 0;
|
|
213
|
+
if (!Object.prototype.hasOwnProperty.call(registry, name)) return void 0;
|
|
214
|
+
return registry[name];
|
|
577
215
|
};
|
|
578
216
|
|
|
579
217
|
// src/theme/typography.ts
|
|
@@ -589,9 +227,9 @@ var captionStyle = (f) => ({
|
|
|
589
227
|
lineHeight: round(f.baseSize * 0.8125 * f.scale * 1.5)
|
|
590
228
|
});
|
|
591
229
|
var labelStyle = (f) => {
|
|
592
|
-
var
|
|
230
|
+
var _a;
|
|
593
231
|
return {
|
|
594
|
-
fontFamily: (
|
|
232
|
+
fontFamily: (_a = f.medium) != null ? _a : f.bold,
|
|
595
233
|
fontSize: round(f.baseSize * f.scale),
|
|
596
234
|
lineHeight: round(f.baseSize * f.scale * 1.4),
|
|
597
235
|
fontWeight: f.medium ? void 0 : "600"
|
|
@@ -604,9 +242,9 @@ var headingStyle = (f) => ({
|
|
|
604
242
|
fontWeight: f.bold ? void 0 : "700"
|
|
605
243
|
});
|
|
606
244
|
var buttonLabelStyle = (f) => {
|
|
607
|
-
var
|
|
245
|
+
var _a;
|
|
608
246
|
return {
|
|
609
|
-
fontFamily: (
|
|
247
|
+
fontFamily: (_a = f.bold) != null ? _a : f.medium,
|
|
610
248
|
fontSize: round(f.baseSize * f.scale),
|
|
611
249
|
fontWeight: f.bold ? void 0 : "600"
|
|
612
250
|
};
|
|
@@ -729,8 +367,8 @@ var stateChangeDuration = (reduced, durationMs) => reduced ? 0 : durationMs;
|
|
|
729
367
|
var loopEnabled = (reduced) => !reduced;
|
|
730
368
|
var lastKnown = false;
|
|
731
369
|
var useReducedMotion = () => {
|
|
732
|
-
const [reduced, setReduced] =
|
|
733
|
-
|
|
370
|
+
const [reduced, setReduced] = React19.useState(lastKnown);
|
|
371
|
+
React19.useEffect(() => {
|
|
734
372
|
let mounted = true;
|
|
735
373
|
reactNative.AccessibilityInfo.isReduceMotionEnabled().then((value) => {
|
|
736
374
|
lastKnown = value;
|
|
@@ -752,8 +390,8 @@ var ROTATION_MS = 1800;
|
|
|
752
390
|
var _AnimatedSparkle = ({ size = 30, color, variant = "spin" }) => {
|
|
753
391
|
const t = useOnboardingTheme();
|
|
754
392
|
const reduced = useReducedMotion();
|
|
755
|
-
const progress =
|
|
756
|
-
|
|
393
|
+
const progress = React19.useRef(new reactNative.Animated.Value(0)).current;
|
|
394
|
+
React19.useEffect(() => {
|
|
757
395
|
if (!loopEnabled(reduced)) {
|
|
758
396
|
progress.setValue(0);
|
|
759
397
|
return;
|
|
@@ -808,7 +446,7 @@ var _AnimatedSparkle = ({ size = 30, color, variant = "spin" }) => {
|
|
|
808
446
|
}
|
|
809
447
|
) });
|
|
810
448
|
};
|
|
811
|
-
var AnimatedSparkle =
|
|
449
|
+
var AnimatedSparkle = React19__default.default.memo(_AnimatedSparkle);
|
|
812
450
|
var styles2 = reactNative.StyleSheet.create({
|
|
813
451
|
box: { alignItems: "center", justifyContent: "center" },
|
|
814
452
|
glyph: {
|
|
@@ -820,8 +458,8 @@ var styles2 = reactNative.StyleSheet.create({
|
|
|
820
458
|
var STAGE_SIZE = 96;
|
|
821
459
|
var ORBIT_DOT = 9;
|
|
822
460
|
var OrbitDot = ({ color, reduced }) => {
|
|
823
|
-
const spin =
|
|
824
|
-
|
|
461
|
+
const spin = React19.useRef(new reactNative.Animated.Value(0)).current;
|
|
462
|
+
React19.useEffect(() => {
|
|
825
463
|
if (!loopEnabled(reduced)) return;
|
|
826
464
|
const loop = reactNative.Animated.loop(
|
|
827
465
|
reactNative.Animated.timing(spin, {
|
|
@@ -844,8 +482,8 @@ var SkeletonLine = ({
|
|
|
844
482
|
color,
|
|
845
483
|
reduced
|
|
846
484
|
}) => {
|
|
847
|
-
const pulse =
|
|
848
|
-
|
|
485
|
+
const pulse = React19.useRef(new reactNative.Animated.Value(1)).current;
|
|
486
|
+
React19.useEffect(() => {
|
|
849
487
|
if (!loopEnabled(reduced)) return;
|
|
850
488
|
const loop = reactNative.Animated.loop(
|
|
851
489
|
reactNative.Animated.sequence([
|
|
@@ -880,8 +518,8 @@ var _LoadingBlock = ({
|
|
|
880
518
|
}) => {
|
|
881
519
|
const t = useOnboardingTheme();
|
|
882
520
|
const reduced = useReducedMotion();
|
|
883
|
-
const [showSkeleton, setShowSkeleton] =
|
|
884
|
-
|
|
521
|
+
const [showSkeleton, setShowSkeleton] = React19.useState(false);
|
|
522
|
+
React19.useEffect(() => {
|
|
885
523
|
const timer = setTimeout(() => setShowSkeleton(true), SKELETON_DELAY_MS);
|
|
886
524
|
return () => clearTimeout(timer);
|
|
887
525
|
}, []);
|
|
@@ -911,7 +549,7 @@ var _LoadingBlock = ({
|
|
|
911
549
|
)
|
|
912
550
|
] });
|
|
913
551
|
};
|
|
914
|
-
var LoadingBlock =
|
|
552
|
+
var LoadingBlock = React19__default.default.memo(_LoadingBlock);
|
|
915
553
|
var styles3 = reactNative.StyleSheet.create({
|
|
916
554
|
center: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
917
555
|
// Absolutely-positioned label column, pinned just under the centered stage: its top
|
|
@@ -956,7 +594,7 @@ var _LoadingScreen = ({ title, hint }) => {
|
|
|
956
594
|
}
|
|
957
595
|
);
|
|
958
596
|
};
|
|
959
|
-
var LoadingScreen =
|
|
597
|
+
var LoadingScreen = React19__default.default.memo(_LoadingScreen);
|
|
960
598
|
var styles4 = reactNative.StyleSheet.create({
|
|
961
599
|
flex: { flex: 1 }
|
|
962
600
|
});
|
|
@@ -975,8 +613,8 @@ var targetFor = (step, complete, approxScreens) => {
|
|
|
975
613
|
var _StepProgress = ({ step, complete, approxScreens }) => {
|
|
976
614
|
const t = useOnboardingTheme();
|
|
977
615
|
const reduced = useReducedMotion();
|
|
978
|
-
const fill =
|
|
979
|
-
|
|
616
|
+
const fill = React19.useRef(new reactNative.Animated.Value(targetFor(step, complete, approxScreens))).current;
|
|
617
|
+
React19.useEffect(() => {
|
|
980
618
|
reactNative.Animated.timing(fill, {
|
|
981
619
|
toValue: targetFor(step, complete, approxScreens),
|
|
982
620
|
duration: scaledMs(stateChangeDuration(reduced, PROGRESS_MS)),
|
|
@@ -996,7 +634,7 @@ var _StepProgress = ({ step, complete, approxScreens }) => {
|
|
|
996
634
|
}
|
|
997
635
|
) });
|
|
998
636
|
};
|
|
999
|
-
var StepProgress =
|
|
637
|
+
var StepProgress = React19__default.default.memo(_StepProgress);
|
|
1000
638
|
var styles5 = reactNative.StyleSheet.create({
|
|
1001
639
|
track: { height: 6, width: "100%", overflow: "hidden" },
|
|
1002
640
|
fill: { height: 6 }
|
|
@@ -1012,31 +650,31 @@ var _OnboardingScaffold = ({
|
|
|
1012
650
|
children
|
|
1013
651
|
}) => {
|
|
1014
652
|
const t = useOnboardingTheme();
|
|
1015
|
-
const
|
|
653
|
+
const styles18 = React19.useMemo(() => makeStyles(t), [t]);
|
|
1016
654
|
const hit = { top: 12, bottom: 12, left: 12, right: 12 };
|
|
1017
655
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1018
656
|
reactNativeSafeAreaContext.SafeAreaView,
|
|
1019
657
|
{
|
|
1020
658
|
edges: ["top", "bottom"],
|
|
1021
|
-
style: [
|
|
659
|
+
style: [styles18.flex, { backgroundColor: t.colors.background }],
|
|
1022
660
|
children: [
|
|
1023
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
1024
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
1025
|
-
onSkip ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.TouchableOpacity, { onPress: onSkip, hitSlop: hit, style:
|
|
661
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles18.header, { paddingHorizontal: t.spacing.md, paddingTop: t.spacing.md }], children: [
|
|
662
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles18.progressWrap, children: /* @__PURE__ */ jsxRuntime.jsx(StepProgress, { step, complete, approxScreens }) }),
|
|
663
|
+
onSkip ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.TouchableOpacity, { onPress: onSkip, hitSlop: hit, style: styles18.skip, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted }], children: skipLabel }) }) : null
|
|
1026
664
|
] }),
|
|
1027
665
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1028
666
|
reactNative.View,
|
|
1029
667
|
{
|
|
1030
|
-
style: [
|
|
668
|
+
style: [styles18.body, { paddingHorizontal: t.spacing.md, paddingTop: t.spacing.md }],
|
|
1031
669
|
children
|
|
1032
670
|
}
|
|
1033
671
|
),
|
|
1034
|
-
onBack ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
672
|
+
onBack ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles18.footer, { paddingHorizontal: t.spacing.md, paddingBottom: t.spacing.sm }], children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.TouchableOpacity, { onPress: onBack, hitSlop: hit, children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted }], children: backLabel }) }) }) : null
|
|
1035
673
|
]
|
|
1036
674
|
}
|
|
1037
675
|
);
|
|
1038
676
|
};
|
|
1039
|
-
var OnboardingScaffold =
|
|
677
|
+
var OnboardingScaffold = React19__default.default.memo(_OnboardingScaffold);
|
|
1040
678
|
function makeStyles(t) {
|
|
1041
679
|
return reactNative.StyleSheet.create({
|
|
1042
680
|
flex: { flex: 1 },
|
|
@@ -1057,8 +695,8 @@ var _Button = ({
|
|
|
1057
695
|
const t = useOnboardingTheme();
|
|
1058
696
|
const reduced = useReducedMotion();
|
|
1059
697
|
const isPrimary = variant === "primary";
|
|
1060
|
-
const pressT =
|
|
1061
|
-
const pressTo =
|
|
698
|
+
const pressT = React19.useRef(new reactNative.Animated.Value(0)).current;
|
|
699
|
+
const pressTo = React19.useCallback(
|
|
1062
700
|
(to) => {
|
|
1063
701
|
if (reduced) {
|
|
1064
702
|
reactNative.Animated.timing(pressT, {
|
|
@@ -1077,16 +715,16 @@ var _Button = ({
|
|
|
1077
715
|
},
|
|
1078
716
|
[pressT, reduced]
|
|
1079
717
|
);
|
|
1080
|
-
const lastPress =
|
|
1081
|
-
const handlePress =
|
|
718
|
+
const lastPress = React19.useRef(0);
|
|
719
|
+
const handlePress = React19.useCallback(() => {
|
|
1082
720
|
if (!onPress) return;
|
|
1083
721
|
const now = Date.now();
|
|
1084
722
|
if (now - lastPress.current < 500) return;
|
|
1085
723
|
lastPress.current = now;
|
|
1086
724
|
onPress();
|
|
1087
725
|
}, [onPress]);
|
|
1088
|
-
const handlePressIn =
|
|
1089
|
-
const handlePressOut =
|
|
726
|
+
const handlePressIn = React19.useCallback(() => pressTo(1), [pressTo]);
|
|
727
|
+
const handlePressOut = React19.useCallback(() => pressTo(0), [pressTo]);
|
|
1090
728
|
const scale = pressT.interpolate({
|
|
1091
729
|
inputRange: [0, 1],
|
|
1092
730
|
outputRange: [1, reduced ? 1 : BUTTON_PRESS_SCALE]
|
|
@@ -1137,7 +775,7 @@ var _Button = ({
|
|
|
1137
775
|
}
|
|
1138
776
|
);
|
|
1139
777
|
};
|
|
1140
|
-
var Button =
|
|
778
|
+
var Button = React19__default.default.memo(_Button);
|
|
1141
779
|
var styles6 = reactNative.StyleSheet.create({
|
|
1142
780
|
base: { alignItems: "center", justifyContent: "center" },
|
|
1143
781
|
fill: { width: "100%" }
|
|
@@ -1155,7 +793,7 @@ var _ErrorBlock = ({
|
|
|
1155
793
|
onRetry ? /* @__PURE__ */ jsxRuntime.jsx(Button, { title: retryLabel, onPress: onRetry, variant: "outline" }) : null
|
|
1156
794
|
] });
|
|
1157
795
|
};
|
|
1158
|
-
var ErrorBlock =
|
|
796
|
+
var ErrorBlock = React19__default.default.memo(_ErrorBlock);
|
|
1159
797
|
var styles7 = reactNative.StyleSheet.create({
|
|
1160
798
|
center: { flex: 1, alignItems: "center", justifyContent: "center" }
|
|
1161
799
|
});
|
|
@@ -1168,10 +806,10 @@ var _CardLayout = ({
|
|
|
1168
806
|
titleNode
|
|
1169
807
|
}) => {
|
|
1170
808
|
const t = useOnboardingTheme();
|
|
1171
|
-
const
|
|
809
|
+
const styles18 = React19.useMemo(() => makeStyles2(t), [t]);
|
|
1172
810
|
const hasHeader = !!title || !!subtitle || !!titleNode;
|
|
1173
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.KeyboardAvoidingView, { style:
|
|
1174
|
-
hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
811
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.KeyboardAvoidingView, { style: styles18.fill, behavior: "padding", children: [
|
|
812
|
+
hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles18.header, children: [
|
|
1175
813
|
titleNode != null ? titleNode : title ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [labelStyle(t.fonts), { color: t.colors.text }], children: title }) : null,
|
|
1176
814
|
subtitle ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1177
815
|
reactNative.Text,
|
|
@@ -1187,10 +825,10 @@ var _CardLayout = ({
|
|
|
1187
825
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1188
826
|
reactNative.ScrollView,
|
|
1189
827
|
{
|
|
1190
|
-
style:
|
|
828
|
+
style: styles18.fill,
|
|
1191
829
|
contentContainerStyle: [
|
|
1192
|
-
|
|
1193
|
-
align === "center" &&
|
|
830
|
+
styles18.scrollContent,
|
|
831
|
+
align === "center" && styles18.center
|
|
1194
832
|
],
|
|
1195
833
|
keyboardShouldPersistTaps: "handled",
|
|
1196
834
|
keyboardDismissMode: "on-drag",
|
|
@@ -1198,10 +836,10 @@ var _CardLayout = ({
|
|
|
1198
836
|
children
|
|
1199
837
|
}
|
|
1200
838
|
),
|
|
1201
|
-
footer ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
839
|
+
footer ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles18.footer, children: footer }) : null
|
|
1202
840
|
] });
|
|
1203
841
|
};
|
|
1204
|
-
var CardLayout =
|
|
842
|
+
var CardLayout = React19__default.default.memo(_CardLayout);
|
|
1205
843
|
function makeStyles2(t) {
|
|
1206
844
|
return reactNative.StyleSheet.create({
|
|
1207
845
|
fill: { flex: 1 },
|
|
@@ -1224,12 +862,12 @@ var _CompletionView = ({
|
|
|
1224
862
|
}) => {
|
|
1225
863
|
const t = useOnboardingTheme();
|
|
1226
864
|
const reduced = useReducedMotion();
|
|
1227
|
-
const [submitted, setSubmitted] =
|
|
1228
|
-
const pop =
|
|
1229
|
-
const burst =
|
|
1230
|
-
const titleT =
|
|
1231
|
-
const messageT =
|
|
1232
|
-
|
|
865
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
866
|
+
const pop = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
867
|
+
const burst = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
868
|
+
const titleT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
869
|
+
const messageT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
870
|
+
React19.useEffect(() => {
|
|
1233
871
|
if (reduced) {
|
|
1234
872
|
pop.setValue(1);
|
|
1235
873
|
burst.setValue(1);
|
|
@@ -1264,7 +902,7 @@ var _CompletionView = ({
|
|
|
1264
902
|
anims.forEach((a) => a.start());
|
|
1265
903
|
return () => anims.forEach((a) => a.stop());
|
|
1266
904
|
}, [reduced, pop, burst, titleT, messageT]);
|
|
1267
|
-
const handlePress =
|
|
905
|
+
const handlePress = React19.useCallback(() => {
|
|
1268
906
|
if (submitted) return;
|
|
1269
907
|
setSubmitted(true);
|
|
1270
908
|
onContinue();
|
|
@@ -1326,7 +964,7 @@ var _CompletionView = ({
|
|
|
1326
964
|
}
|
|
1327
965
|
);
|
|
1328
966
|
};
|
|
1329
|
-
var CompletionView =
|
|
967
|
+
var CompletionView = React19__default.default.memo(_CompletionView);
|
|
1330
968
|
var styles8 = reactNative.StyleSheet.create({
|
|
1331
969
|
center: { width: "100%", alignItems: "center", justifyContent: "center" },
|
|
1332
970
|
badgeStage: {
|
|
@@ -1348,14 +986,14 @@ var _CardHandoff = ({
|
|
|
1348
986
|
children
|
|
1349
987
|
}) => {
|
|
1350
988
|
const reduced = useReducedMotion();
|
|
1351
|
-
const [leaving, setLeaving] =
|
|
1352
|
-
const enterT =
|
|
1353
|
-
const exitT =
|
|
1354
|
-
const prev =
|
|
1355
|
-
const running =
|
|
1356
|
-
const mounted =
|
|
1357
|
-
|
|
1358
|
-
var
|
|
989
|
+
const [leaving, setLeaving] = React19.useState(null);
|
|
990
|
+
const enterT = React19.useRef(new reactNative.Animated.Value(0)).current;
|
|
991
|
+
const exitT = React19.useRef(new reactNative.Animated.Value(0)).current;
|
|
992
|
+
const prev = React19.useRef({ key: transitionKey, node: children, variant });
|
|
993
|
+
const running = React19.useRef({});
|
|
994
|
+
const mounted = React19.useRef(false);
|
|
995
|
+
React19.useEffect(() => {
|
|
996
|
+
var _a, _b;
|
|
1359
997
|
const last = prev.current;
|
|
1360
998
|
prev.current = { key: transitionKey, node: children, variant };
|
|
1361
999
|
if (!mounted.current) {
|
|
@@ -1364,7 +1002,7 @@ var _CardHandoff = ({
|
|
|
1364
1002
|
return;
|
|
1365
1003
|
}
|
|
1366
1004
|
if (last.key === transitionKey) return;
|
|
1367
|
-
(
|
|
1005
|
+
(_a = running.current.enter) == null ? void 0 : _a.stop();
|
|
1368
1006
|
(_b = running.current.exit) == null ? void 0 : _b.stop();
|
|
1369
1007
|
setLeaving(last);
|
|
1370
1008
|
enterT.setValue(0);
|
|
@@ -1387,10 +1025,10 @@ var _CardHandoff = ({
|
|
|
1387
1025
|
);
|
|
1388
1026
|
running.current.enter = enter;
|
|
1389
1027
|
});
|
|
1390
|
-
|
|
1028
|
+
React19.useEffect(
|
|
1391
1029
|
() => () => {
|
|
1392
|
-
var
|
|
1393
|
-
(
|
|
1030
|
+
var _a, _b;
|
|
1031
|
+
(_a = running.current.enter) == null ? void 0 : _a.stop();
|
|
1394
1032
|
(_b = running.current.exit) == null ? void 0 : _b.stop();
|
|
1395
1033
|
},
|
|
1396
1034
|
[]
|
|
@@ -1456,7 +1094,7 @@ var transformFor = (variant, t, reduced, layer, travel) => {
|
|
|
1456
1094
|
}
|
|
1457
1095
|
];
|
|
1458
1096
|
};
|
|
1459
|
-
var CardHandoff =
|
|
1097
|
+
var CardHandoff = React19__default.default.memo(_CardHandoff);
|
|
1460
1098
|
var styles9 = reactNative.StyleSheet.create({
|
|
1461
1099
|
fill: { flex: 1 }
|
|
1462
1100
|
});
|
|
@@ -1471,13 +1109,13 @@ var tryParse = (s) => {
|
|
|
1471
1109
|
}
|
|
1472
1110
|
};
|
|
1473
1111
|
var deriveAnswers = (messages) => {
|
|
1474
|
-
var
|
|
1112
|
+
var _a, _b, _c;
|
|
1475
1113
|
const out = {};
|
|
1476
1114
|
for (let i = 0; i < messages.length; i++) {
|
|
1477
1115
|
const m = messages[i];
|
|
1478
1116
|
const r = m == null ? void 0 : m.response;
|
|
1479
1117
|
if (!m || m.role !== "assistant" || !r || r.action !== "render") continue;
|
|
1480
|
-
const props = (
|
|
1118
|
+
const props = (_a = r.props) != null ? _a : {};
|
|
1481
1119
|
const progress = props.progress;
|
|
1482
1120
|
const questionText = (_c = (_b = props.title) != null ? _b : props.label) != null ? _c : props.question;
|
|
1483
1121
|
const key = (progress == null ? void 0 : progress.slot_id) || (progress == null ? void 0 : progress.key) || questionText;
|
|
@@ -1491,9 +1129,9 @@ var deriveAnswers = (messages) => {
|
|
|
1491
1129
|
|
|
1492
1130
|
// src/utils/readProgress.ts
|
|
1493
1131
|
var readProgress = (response) => {
|
|
1494
|
-
var
|
|
1132
|
+
var _a;
|
|
1495
1133
|
if (!response || response.action !== "render") return {};
|
|
1496
|
-
const props = (
|
|
1134
|
+
const props = (_a = response.props) != null ? _a : {};
|
|
1497
1135
|
const raw = props.progress;
|
|
1498
1136
|
if (!raw || typeof raw !== "object") return {};
|
|
1499
1137
|
const p = raw;
|
|
@@ -1509,13 +1147,24 @@ var readProgress = (response) => {
|
|
|
1509
1147
|
|
|
1510
1148
|
// src/analytics/reportClientEvent.ts
|
|
1511
1149
|
var makeSessionId = () => `wire_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1150
|
+
var toWireEvents = (events) => events.map((event) => {
|
|
1151
|
+
if (typeof event.ts !== "number") return event;
|
|
1152
|
+
const { ts, ...rest } = event;
|
|
1153
|
+
if (!Number.isFinite(ts)) return rest;
|
|
1154
|
+
try {
|
|
1155
|
+
return { ...rest, ts: new Date(ts).toISOString() };
|
|
1156
|
+
} catch {
|
|
1157
|
+
return rest;
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1512
1160
|
var buildEventsRequest = (target, events) => {
|
|
1513
1161
|
if (!(target == null ? void 0 : target.serverUrl) || events.length === 0) return null;
|
|
1514
1162
|
try {
|
|
1515
1163
|
const url = `${target.serverUrl.replace(/\/$/, "")}/v1/events`;
|
|
1516
1164
|
const headers = { "Content-Type": "application/json" };
|
|
1517
1165
|
if (target.apiKey) headers.Authorization = `Bearer ${target.apiKey}`;
|
|
1518
|
-
|
|
1166
|
+
const body = JSON.stringify({ events: toWireEvents(events) });
|
|
1167
|
+
return { url, init: { method: "POST", headers, body } };
|
|
1519
1168
|
} catch {
|
|
1520
1169
|
return null;
|
|
1521
1170
|
}
|
|
@@ -1527,7 +1176,13 @@ var readEventsAck = async (res) => {
|
|
|
1527
1176
|
const body = await Promise.resolve(json.call(res));
|
|
1528
1177
|
const skipped = body == null ? void 0 : body.skipped;
|
|
1529
1178
|
if (typeof skipped !== "number" || !Number.isFinite(skipped)) return void 0;
|
|
1530
|
-
const reasons = Array.isArray(body == null ? void 0 : body.errors) ? body.errors.map((e) =>
|
|
1179
|
+
const reasons = Array.isArray(body == null ? void 0 : body.errors) ? body.errors.map((e) => {
|
|
1180
|
+
const entry = e;
|
|
1181
|
+
const reason = entry == null ? void 0 : entry.reason;
|
|
1182
|
+
if (typeof reason !== "string") return void 0;
|
|
1183
|
+
const field = entry == null ? void 0 : entry.field;
|
|
1184
|
+
return typeof field === "string" && field.length > 0 ? `${reason} (field: ${field})` : reason;
|
|
1185
|
+
}).filter((r) => typeof r === "string") : [];
|
|
1531
1186
|
return { written: typeof (body == null ? void 0 : body.written) === "number" ? body.written : void 0, skipped, reasons };
|
|
1532
1187
|
} catch {
|
|
1533
1188
|
return void 0;
|
|
@@ -1597,6 +1252,382 @@ var sendPreview = (target, { sessionId, userMessage }) => {
|
|
|
1597
1252
|
} catch {
|
|
1598
1253
|
}
|
|
1599
1254
|
};
|
|
1255
|
+
|
|
1256
|
+
// src/permissions/permissionEvents.ts
|
|
1257
|
+
var WIRE_PERMISSION_EVENTS = {
|
|
1258
|
+
/** The priming screen became visible. The denominator for every rate below. */
|
|
1259
|
+
screenShown: "wire_permission_screen_shown",
|
|
1260
|
+
/** The user tapped the primary, so the OS dialog is about to open. The rationale worked. */
|
|
1261
|
+
primerAccepted: "wire_permission_primer_accepted",
|
|
1262
|
+
/** The OS granted it. */
|
|
1263
|
+
granted: "wire_permission_granted",
|
|
1264
|
+
/** The OS refused it (a permanently blocked answer reports here too, with `status: "blocked"`). */
|
|
1265
|
+
denied: "wire_permission_denied",
|
|
1266
|
+
/** The user took the secondary. The one native prompt was NOT spent. */
|
|
1267
|
+
skipped: "wire_permission_skipped",
|
|
1268
|
+
/** A blocked user was redirected to the OS settings page. */
|
|
1269
|
+
settingsOpened: "wire_permission_settings_opened"
|
|
1270
|
+
};
|
|
1271
|
+
var permissionEventName = (stage) => {
|
|
1272
|
+
switch (stage) {
|
|
1273
|
+
case "shown":
|
|
1274
|
+
return WIRE_PERMISSION_EVENTS.screenShown;
|
|
1275
|
+
case "accepted":
|
|
1276
|
+
return WIRE_PERMISSION_EVENTS.primerAccepted;
|
|
1277
|
+
case "granted":
|
|
1278
|
+
return WIRE_PERMISSION_EVENTS.granted;
|
|
1279
|
+
case "denied":
|
|
1280
|
+
return WIRE_PERMISSION_EVENTS.denied;
|
|
1281
|
+
case "skipped":
|
|
1282
|
+
return WIRE_PERMISSION_EVENTS.skipped;
|
|
1283
|
+
case "settings":
|
|
1284
|
+
return WIRE_PERMISSION_EVENTS.settingsOpened;
|
|
1285
|
+
default: {
|
|
1286
|
+
const _exhaustive = stage;
|
|
1287
|
+
return _exhaustive;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
};
|
|
1291
|
+
var permissionEventProps = (permission, status) => status ? { permission, status } : { permission };
|
|
1292
|
+
var normalizePermissionStatus = (value) => value === "granted" || value === "denied" || value === "blocked" ? value : "denied";
|
|
1293
|
+
|
|
1294
|
+
// src/haptics/haptics.ts
|
|
1295
|
+
var play = async (tone) => {
|
|
1296
|
+
try {
|
|
1297
|
+
const mod = await import('expo-haptics');
|
|
1298
|
+
if (!mod) return false;
|
|
1299
|
+
if (tone === "selection") ;
|
|
1300
|
+
if (tone === "light") ;
|
|
1301
|
+
await mod.notificationAsync(mod.NotificationFeedbackType.Success);
|
|
1302
|
+
return true;
|
|
1303
|
+
} catch {
|
|
1304
|
+
return false;
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
var playHaptic = (tone) => {
|
|
1308
|
+
void play(tone);
|
|
1309
|
+
};
|
|
1310
|
+
|
|
1311
|
+
// src/utils/warnInDev.ts
|
|
1312
|
+
var warnInDev = (message) => {
|
|
1313
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
1314
|
+
console.warn(message);
|
|
1315
|
+
return true;
|
|
1316
|
+
}
|
|
1317
|
+
return false;
|
|
1318
|
+
};
|
|
1319
|
+
var easeWire4 = reactNative.Easing.bezier(...WIRE_BEZIER);
|
|
1320
|
+
var RISE_PX = 10;
|
|
1321
|
+
var PERMISSION_CARD_NAME = "PermissionCard";
|
|
1322
|
+
var REQUEST_WATCHDOG_MS = 9e4;
|
|
1323
|
+
var schema = zod.z.object({
|
|
1324
|
+
permission: zod.z.string().describe("Which OS permission this screen primes, e.g. 'notifications'"),
|
|
1325
|
+
title: zod.z.string().describe("Headline for the ask"),
|
|
1326
|
+
message: zod.z.string().describe("Why the app needs it, in the user's terms"),
|
|
1327
|
+
primaryLabel: zod.z.string().describe("Primary button, the only control that can open the OS dialog"),
|
|
1328
|
+
secondaryLabel: zod.z.string().describe("Secondary button, advances without spending the OS prompt"),
|
|
1329
|
+
blockedTitle: zod.z.string().optional().describe("Headline once the permission is permanently refused"),
|
|
1330
|
+
blockedMessage: zod.z.string().optional().describe("Rationale for the settings route"),
|
|
1331
|
+
settingsLabel: zod.z.string().optional().describe("Primary button label on the blocked route"),
|
|
1332
|
+
continueLabel: zod.z.string().optional().describe("Primary button label when there is nothing to ask"),
|
|
1333
|
+
illustration: zod.z.string().optional().describe("Name of an app-provided illustration (defaults to the permission name)")
|
|
1334
|
+
});
|
|
1335
|
+
var _PermissionCard = ({
|
|
1336
|
+
permission,
|
|
1337
|
+
title,
|
|
1338
|
+
message,
|
|
1339
|
+
primaryLabel,
|
|
1340
|
+
secondaryLabel,
|
|
1341
|
+
blockedTitle,
|
|
1342
|
+
blockedMessage,
|
|
1343
|
+
settingsLabel,
|
|
1344
|
+
continueLabel,
|
|
1345
|
+
illustration,
|
|
1346
|
+
request,
|
|
1347
|
+
getStatus,
|
|
1348
|
+
openSettings,
|
|
1349
|
+
onStage,
|
|
1350
|
+
onSettled
|
|
1351
|
+
}) => {
|
|
1352
|
+
const t = useOnboardingTheme();
|
|
1353
|
+
const reduced = useReducedMotion();
|
|
1354
|
+
const art = useIllustration(illustration != null ? illustration : permission);
|
|
1355
|
+
const [status, setStatus] = React19.useState(void 0);
|
|
1356
|
+
const [busy, setBusy] = React19.useState(false);
|
|
1357
|
+
const settledRef = React19.useRef(false);
|
|
1358
|
+
const acceptedRef = React19.useRef(false);
|
|
1359
|
+
const watchdogRef = React19.useRef(null);
|
|
1360
|
+
const clearWatchdog = React19.useCallback(() => {
|
|
1361
|
+
if (watchdogRef.current) {
|
|
1362
|
+
clearTimeout(watchdogRef.current);
|
|
1363
|
+
watchdogRef.current = null;
|
|
1364
|
+
}
|
|
1365
|
+
}, []);
|
|
1366
|
+
React19.useEffect(() => clearWatchdog, [clearWatchdog]);
|
|
1367
|
+
const onStageRef = React19.useRef(onStage);
|
|
1368
|
+
onStageRef.current = onStage;
|
|
1369
|
+
const onSettledRef = React19.useRef(onSettled);
|
|
1370
|
+
onSettledRef.current = onSettled;
|
|
1371
|
+
const getStatusRef = React19.useRef(getStatus);
|
|
1372
|
+
getStatusRef.current = getStatus;
|
|
1373
|
+
const shownRef = React19.useRef(false);
|
|
1374
|
+
React19.useEffect(() => {
|
|
1375
|
+
var _a;
|
|
1376
|
+
if (shownRef.current) return;
|
|
1377
|
+
shownRef.current = true;
|
|
1378
|
+
(_a = onStageRef.current) == null ? void 0 : _a.call(onStageRef, "shown");
|
|
1379
|
+
}, []);
|
|
1380
|
+
React19.useEffect(() => {
|
|
1381
|
+
const probe = getStatusRef.current;
|
|
1382
|
+
if (!probe) return;
|
|
1383
|
+
let cancelled = false;
|
|
1384
|
+
try {
|
|
1385
|
+
void Promise.resolve(probe()).then((value) => {
|
|
1386
|
+
if (!cancelled) setStatus(normalizePermissionStatus(value));
|
|
1387
|
+
}).catch(() => {
|
|
1388
|
+
});
|
|
1389
|
+
} catch {
|
|
1390
|
+
}
|
|
1391
|
+
return () => {
|
|
1392
|
+
cancelled = true;
|
|
1393
|
+
};
|
|
1394
|
+
}, []);
|
|
1395
|
+
const requestRef = React19.useRef(request);
|
|
1396
|
+
requestRef.current = request;
|
|
1397
|
+
React19.useEffect(() => {
|
|
1398
|
+
if (requestRef.current) return;
|
|
1399
|
+
warnInDev(
|
|
1400
|
+
`[wireai] <WireOnboarding> got a permission screen for "${permission}" with no \`request\` function, so it cannot open the OS dialog and renders as a plain continue. Pass request: () => Promise<'granted' | 'denied' | 'blocked'> (5 lines around expo-notifications, see the README).`
|
|
1401
|
+
);
|
|
1402
|
+
}, [permission]);
|
|
1403
|
+
const settle = React19.useCallback((outcome) => {
|
|
1404
|
+
var _a;
|
|
1405
|
+
if (settledRef.current) return;
|
|
1406
|
+
settledRef.current = true;
|
|
1407
|
+
clearWatchdog();
|
|
1408
|
+
(_a = onSettledRef.current) == null ? void 0 : _a.call(onSettledRef, outcome);
|
|
1409
|
+
}, [clearWatchdog]);
|
|
1410
|
+
const primaryAction = status === "blocked" ? "settings" : status === "granted" || !request ? "continue" : "ask";
|
|
1411
|
+
const handlePrimary = React19.useCallback(() => {
|
|
1412
|
+
var _a, _b, _c, _d;
|
|
1413
|
+
if (settledRef.current || busy) return;
|
|
1414
|
+
if (primaryAction === "settings") {
|
|
1415
|
+
(_a = onStageRef.current) == null ? void 0 : _a.call(onStageRef, "settings", "blocked");
|
|
1416
|
+
try {
|
|
1417
|
+
void Promise.resolve(openSettings == null ? void 0 : openSettings()).catch(() => {
|
|
1418
|
+
});
|
|
1419
|
+
} catch {
|
|
1420
|
+
}
|
|
1421
|
+
settle("blocked");
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
if (primaryAction === "continue") {
|
|
1425
|
+
if (status === "granted") {
|
|
1426
|
+
(_b = onStageRef.current) == null ? void 0 : _b.call(onStageRef, "granted", "granted");
|
|
1427
|
+
settle("granted");
|
|
1428
|
+
} else {
|
|
1429
|
+
(_c = onStageRef.current) == null ? void 0 : _c.call(onStageRef, "skipped");
|
|
1430
|
+
settle("skipped");
|
|
1431
|
+
}
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
if (!acceptedRef.current) {
|
|
1435
|
+
acceptedRef.current = true;
|
|
1436
|
+
(_d = onStageRef.current) == null ? void 0 : _d.call(onStageRef, "accepted");
|
|
1437
|
+
}
|
|
1438
|
+
setBusy(true);
|
|
1439
|
+
const finish = (value) => {
|
|
1440
|
+
var _a2, _b2;
|
|
1441
|
+
if (settledRef.current) return;
|
|
1442
|
+
clearWatchdog();
|
|
1443
|
+
const resolved = normalizePermissionStatus(value);
|
|
1444
|
+
setBusy(false);
|
|
1445
|
+
setStatus(resolved);
|
|
1446
|
+
if (resolved === "granted") {
|
|
1447
|
+
playHaptic("success");
|
|
1448
|
+
(_a2 = onStageRef.current) == null ? void 0 : _a2.call(onStageRef, "granted", "granted");
|
|
1449
|
+
} else {
|
|
1450
|
+
(_b2 = onStageRef.current) == null ? void 0 : _b2.call(onStageRef, "denied", resolved);
|
|
1451
|
+
}
|
|
1452
|
+
settle(resolved);
|
|
1453
|
+
};
|
|
1454
|
+
clearWatchdog();
|
|
1455
|
+
watchdogRef.current = setTimeout(() => {
|
|
1456
|
+
watchdogRef.current = null;
|
|
1457
|
+
if (settledRef.current) return;
|
|
1458
|
+
setBusy(false);
|
|
1459
|
+
warnInDev(
|
|
1460
|
+
`[wireai] the \`request\` for the "${permission}" permission screen has not settled after ${Math.round(REQUEST_WATCHDOG_MS / 1e3)}s, so the kit handed the controls back rather than leaving the user on a dead-end screen. It recorded NO outcome, because a pending request is not a denial. Make sure your request resolves to 'granted' | 'denied' | 'blocked' on every branch, including the one where the user dismisses the OS dialog.`
|
|
1461
|
+
);
|
|
1462
|
+
}, REQUEST_WATCHDOG_MS);
|
|
1463
|
+
try {
|
|
1464
|
+
void Promise.resolve(request == null ? void 0 : request()).then(finish, () => finish("denied"));
|
|
1465
|
+
} catch {
|
|
1466
|
+
finish("denied");
|
|
1467
|
+
}
|
|
1468
|
+
}, [busy, primaryAction, status, request, openSettings, settle, clearWatchdog, permission]);
|
|
1469
|
+
const handleSecondary = React19.useCallback(() => {
|
|
1470
|
+
var _a;
|
|
1471
|
+
if (settledRef.current || busy) return;
|
|
1472
|
+
(_a = onStageRef.current) == null ? void 0 : _a.call(onStageRef, "skipped");
|
|
1473
|
+
settle("skipped");
|
|
1474
|
+
}, [busy, settle]);
|
|
1475
|
+
const popT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
1476
|
+
const titleT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
1477
|
+
const bodyT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
1478
|
+
React19.useEffect(() => {
|
|
1479
|
+
if (reduced) {
|
|
1480
|
+
popT.setValue(1);
|
|
1481
|
+
titleT.setValue(1);
|
|
1482
|
+
bodyT.setValue(1);
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1485
|
+
const rise = (value, delay) => reactNative.Animated.timing(value, {
|
|
1486
|
+
toValue: 1,
|
|
1487
|
+
duration: scaledMs(INTERSTITIAL_HEAD_MS),
|
|
1488
|
+
delay,
|
|
1489
|
+
easing: easeWire4,
|
|
1490
|
+
useNativeDriver: true
|
|
1491
|
+
});
|
|
1492
|
+
const anims = [
|
|
1493
|
+
reactNative.Animated.spring(popT, {
|
|
1494
|
+
toValue: 1,
|
|
1495
|
+
friction: STATUS_POP_SPRING.friction,
|
|
1496
|
+
tension: STATUS_POP_SPRING.tension,
|
|
1497
|
+
useNativeDriver: true
|
|
1498
|
+
}),
|
|
1499
|
+
rise(titleT, scaledMs(INTERSTITIAL_HEAD_STAGGER_MS)),
|
|
1500
|
+
rise(bodyT, scaledMs(INTERSTITIAL_HEAD_STAGGER_MS * 2))
|
|
1501
|
+
];
|
|
1502
|
+
anims.forEach((a) => a.start());
|
|
1503
|
+
return () => anims.forEach((a) => a.stop());
|
|
1504
|
+
}, [reduced, popT, titleT, bodyT]);
|
|
1505
|
+
const popScale = popT.interpolate({
|
|
1506
|
+
inputRange: [0, 1],
|
|
1507
|
+
outputRange: [STATUS_POP_SCALE_FROM, 1]
|
|
1508
|
+
});
|
|
1509
|
+
const riseStyle = (value) => ({
|
|
1510
|
+
opacity: value,
|
|
1511
|
+
transform: [
|
|
1512
|
+
{ translateY: value.interpolate({ inputRange: [0, 1], outputRange: [RISE_PX, 0] }) }
|
|
1513
|
+
]
|
|
1514
|
+
});
|
|
1515
|
+
const blocked = status === "blocked";
|
|
1516
|
+
const shownTitle = blocked ? blockedTitle != null ? blockedTitle : title : title;
|
|
1517
|
+
const shownMessage = blocked ? blockedMessage != null ? blockedMessage : message : message;
|
|
1518
|
+
const primaryTitle = primaryAction === "settings" ? settingsLabel != null ? settingsLabel : primaryLabel : primaryAction === "continue" ? continueLabel != null ? continueLabel : primaryLabel : primaryLabel;
|
|
1519
|
+
const showSecondary = status !== "granted";
|
|
1520
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1521
|
+
CardLayout,
|
|
1522
|
+
{
|
|
1523
|
+
align: "center",
|
|
1524
|
+
footer: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles10.footer, { gap: t.spacing.sm }], children: [
|
|
1525
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { title: primaryTitle, onPress: handlePrimary, variant: "primary", disabled: busy }),
|
|
1526
|
+
showSecondary ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1527
|
+
Button,
|
|
1528
|
+
{
|
|
1529
|
+
title: secondaryLabel,
|
|
1530
|
+
onPress: handleSecondary,
|
|
1531
|
+
variant: "outline",
|
|
1532
|
+
disabled: busy
|
|
1533
|
+
}
|
|
1534
|
+
) : null
|
|
1535
|
+
] }),
|
|
1536
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles10.center, { gap: t.spacing.md }], children: [
|
|
1537
|
+
art ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1538
|
+
reactNative.Animated.View,
|
|
1539
|
+
{
|
|
1540
|
+
style: [styles10.art, { opacity: popT, transform: [{ scale: popScale }] }],
|
|
1541
|
+
children: art
|
|
1542
|
+
}
|
|
1543
|
+
) : null,
|
|
1544
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: riseStyle(titleT), children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [headingStyle(t.fonts), { color: t.colors.text, textAlign: "center" }], children: shownTitle }) }),
|
|
1545
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: riseStyle(bodyT), children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted, textAlign: "center" }], children: shownMessage }) })
|
|
1546
|
+
] })
|
|
1547
|
+
}
|
|
1548
|
+
);
|
|
1549
|
+
};
|
|
1550
|
+
var PermissionCardView = React19__default.default.memo(_PermissionCard);
|
|
1551
|
+
var PermissionCard = {
|
|
1552
|
+
name: PERMISSION_CARD_NAME,
|
|
1553
|
+
description: "A priming screen shown BEFORE an OS permission dialog: it explains why the app wants the permission and asks only on the primary tap. Never first, never last. The user is never blocked by it: the secondary advances the flow with the OS prompt unspent.",
|
|
1554
|
+
component: PermissionCardView,
|
|
1555
|
+
propsSchema: schema
|
|
1556
|
+
};
|
|
1557
|
+
var styles10 = reactNative.StyleSheet.create({
|
|
1558
|
+
center: { width: "100%", alignItems: "center", justifyContent: "center" },
|
|
1559
|
+
art: { alignItems: "center", justifyContent: "center" },
|
|
1560
|
+
footer: { width: "100%", alignItems: "center" }
|
|
1561
|
+
});
|
|
1562
|
+
|
|
1563
|
+
// src/permissions/placement.ts
|
|
1564
|
+
var DEFAULT_PERMISSION_PLACEMENT = "beforeEnd";
|
|
1565
|
+
var normalizeAfterCard = (value) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : 0;
|
|
1566
|
+
var targetIndex = (placement) => {
|
|
1567
|
+
if (placement === "beforeEnd") return void 0;
|
|
1568
|
+
if (placement === "start") return 0;
|
|
1569
|
+
return normalizeAfterCard(placement.afterCard);
|
|
1570
|
+
};
|
|
1571
|
+
var isPermissionDue = (placement, position) => {
|
|
1572
|
+
if (position.cardIndex < 0) return false;
|
|
1573
|
+
const target = targetIndex(placement);
|
|
1574
|
+
if (target === void 0) return position.isTerminal;
|
|
1575
|
+
return position.cardIndex >= target || position.isTerminal;
|
|
1576
|
+
};
|
|
1577
|
+
var permissionScreenId = (screen, index) => {
|
|
1578
|
+
var _a;
|
|
1579
|
+
return (_a = screen.id) != null ? _a : `${screen.permission}:${index}`;
|
|
1580
|
+
};
|
|
1581
|
+
var selectDuePermissionScreen = (screens, settled, position) => {
|
|
1582
|
+
var _a;
|
|
1583
|
+
if (!screens || screens.length === 0) return void 0;
|
|
1584
|
+
for (let index = 0; index < screens.length; index++) {
|
|
1585
|
+
const screen = screens[index];
|
|
1586
|
+
if (!screen) continue;
|
|
1587
|
+
const id = permissionScreenId(screen, index);
|
|
1588
|
+
if (settled.includes(id)) continue;
|
|
1589
|
+
if (isPermissionDue((_a = screen.placement) != null ? _a : DEFAULT_PERMISSION_PLACEMENT, position)) {
|
|
1590
|
+
return { screen, id };
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
return void 0;
|
|
1594
|
+
};
|
|
1595
|
+
|
|
1596
|
+
// src/permissions/permissionCopy.ts
|
|
1597
|
+
var NOTIFICATIONS_PERMISSION_COPY = {
|
|
1598
|
+
title: "Want a nudge at the right moment?",
|
|
1599
|
+
message: "Turn notifications on and we will remind you when it actually helps. No daily noise, and you can turn them off any time.",
|
|
1600
|
+
primaryLabel: "Enable notifications",
|
|
1601
|
+
secondaryLabel: "Maybe later",
|
|
1602
|
+
blockedTitle: "Notifications are switched off",
|
|
1603
|
+
blockedMessage: "Notifications are turned off for this app, so we cannot ask from here. You can switch them back on in Settings.",
|
|
1604
|
+
settingsLabel: "Open settings",
|
|
1605
|
+
continueLabel: "Continue"
|
|
1606
|
+
};
|
|
1607
|
+
var GENERIC_PERMISSION_COPY = {
|
|
1608
|
+
title: "One quick permission",
|
|
1609
|
+
message: "We need your permission for this part to work. You can change it any time.",
|
|
1610
|
+
primaryLabel: "Allow",
|
|
1611
|
+
secondaryLabel: "Maybe later",
|
|
1612
|
+
blockedTitle: "Permission is switched off",
|
|
1613
|
+
blockedMessage: "This permission is turned off for this app, so we cannot ask from here. You can switch it back on in Settings.",
|
|
1614
|
+
settingsLabel: "Open settings",
|
|
1615
|
+
continueLabel: "Continue"
|
|
1616
|
+
};
|
|
1617
|
+
var DEFAULT_PERMISSION_COPY = {
|
|
1618
|
+
notifications: NOTIFICATIONS_PERMISSION_COPY
|
|
1619
|
+
};
|
|
1620
|
+
var resolvePermissionCopy = (permission, overrides) => {
|
|
1621
|
+
var _a;
|
|
1622
|
+
const base = (_a = DEFAULT_PERMISSION_COPY[permission]) != null ? _a : GENERIC_PERMISSION_COPY;
|
|
1623
|
+
if (!overrides) return base;
|
|
1624
|
+
const merged = { ...base };
|
|
1625
|
+
for (const key of Object.keys(overrides)) {
|
|
1626
|
+
const value = overrides[key];
|
|
1627
|
+
if (typeof value === "string" && value.length > 0) merged[key] = value;
|
|
1628
|
+
}
|
|
1629
|
+
return merged;
|
|
1630
|
+
};
|
|
1600
1631
|
var SKIP_ONE_SENTINEL = "__wireai_skip__";
|
|
1601
1632
|
var ANSWER_CALLBACKS = ["onSubmit", "onSelect", "onConfirm", "onPress"];
|
|
1602
1633
|
var DEFAULT_COPY = {
|
|
@@ -1625,72 +1656,82 @@ var OnboardingFlow = ({
|
|
|
1625
1656
|
reportTarget,
|
|
1626
1657
|
sessionId,
|
|
1627
1658
|
resumed = false,
|
|
1628
|
-
clientContext
|
|
1659
|
+
clientContext,
|
|
1660
|
+
permissionScreens,
|
|
1661
|
+
settledPermissions,
|
|
1662
|
+
permissionsPending = false,
|
|
1663
|
+
onPermissionSettled
|
|
1629
1664
|
}) => {
|
|
1630
|
-
var
|
|
1665
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1631
1666
|
const { messages, error, isLoading, sendMessage, reset } = wireaiRn.useWireAIThread();
|
|
1632
1667
|
const makeActions = wireaiRn.useWireAIAction(sendMessage);
|
|
1633
|
-
const c =
|
|
1634
|
-
const onEventRef =
|
|
1668
|
+
const c = React19.useMemo(() => ({ ...DEFAULT_COPY, ...copy }), [copy]);
|
|
1669
|
+
const onEventRef = React19.useRef(onEvent);
|
|
1635
1670
|
onEventRef.current = onEvent;
|
|
1636
|
-
const onErrorRef =
|
|
1671
|
+
const onErrorRef = React19.useRef(onError);
|
|
1637
1672
|
onErrorRef.current = onError;
|
|
1638
|
-
const onCompleteRef =
|
|
1673
|
+
const onCompleteRef = React19.useRef(onComplete);
|
|
1639
1674
|
onCompleteRef.current = onComplete;
|
|
1640
|
-
const validatorsRef =
|
|
1675
|
+
const validatorsRef = React19.useRef(validators);
|
|
1641
1676
|
validatorsRef.current = validators;
|
|
1642
|
-
const reportTargetRef =
|
|
1677
|
+
const reportTargetRef = React19.useRef(reportTarget);
|
|
1643
1678
|
reportTargetRef.current = reportTarget;
|
|
1644
|
-
const sessionIdRef =
|
|
1679
|
+
const sessionIdRef = React19.useRef(sessionId);
|
|
1645
1680
|
sessionIdRef.current = sessionId;
|
|
1646
|
-
const clientContextRef =
|
|
1681
|
+
const clientContextRef = React19.useRef(clientContext);
|
|
1647
1682
|
clientContextRef.current = clientContext;
|
|
1648
|
-
const lastScreenIndexRef =
|
|
1649
|
-
const previewTimer =
|
|
1650
|
-
const
|
|
1651
|
-
const
|
|
1652
|
-
const
|
|
1653
|
-
const
|
|
1654
|
-
const
|
|
1655
|
-
const
|
|
1656
|
-
const [
|
|
1657
|
-
const [
|
|
1658
|
-
const [
|
|
1659
|
-
const
|
|
1683
|
+
const lastScreenIndexRef = React19.useRef(-1);
|
|
1684
|
+
const previewTimer = React19.useRef(null);
|
|
1685
|
+
const [runId, setRunId] = React19.useState(0);
|
|
1686
|
+
const startedRunRef = React19.useRef(-1);
|
|
1687
|
+
const finished = React19.useRef(false);
|
|
1688
|
+
const errored = React19.useRef(false);
|
|
1689
|
+
const attempts = React19.useRef(0);
|
|
1690
|
+
const degradedRef = React19.useRef(false);
|
|
1691
|
+
const [degraded, setDegraded] = React19.useState(false);
|
|
1692
|
+
const [timedOut, setTimedOut] = React19.useState(false);
|
|
1693
|
+
const [validationError, setValidationError] = React19.useState();
|
|
1694
|
+
const [validating, setValidating] = React19.useState(false);
|
|
1695
|
+
const [locallySettledPermissions, setLocallySettledPermissions] = React19.useState([]);
|
|
1696
|
+
const onPermissionSettledRef = React19.useRef(onPermissionSettled);
|
|
1697
|
+
onPermissionSettledRef.current = onPermissionSettled;
|
|
1698
|
+
const lastCard = React19.useMemo(
|
|
1660
1699
|
() => [...messages].reverse().find((m) => {
|
|
1661
|
-
var
|
|
1662
|
-
return m.role === "assistant" && ((
|
|
1700
|
+
var _a2;
|
|
1701
|
+
return m.role === "assistant" && ((_a2 = m.response) == null ? void 0 : _a2.action) === "render";
|
|
1663
1702
|
}),
|
|
1664
1703
|
[messages]
|
|
1665
1704
|
);
|
|
1666
|
-
const renderedCount =
|
|
1705
|
+
const renderedCount = React19.useMemo(
|
|
1667
1706
|
() => messages.filter((m) => {
|
|
1668
|
-
var
|
|
1669
|
-
return m.role === "assistant" && ((
|
|
1707
|
+
var _a2;
|
|
1708
|
+
return m.role === "assistant" && ((_a2 = m.response) == null ? void 0 : _a2.action) === "render";
|
|
1670
1709
|
}).length,
|
|
1671
1710
|
[messages]
|
|
1672
1711
|
);
|
|
1673
|
-
const progress =
|
|
1674
|
-
|
|
1675
|
-
var
|
|
1676
|
-
if (
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
(
|
|
1712
|
+
const progress = React19.useMemo(() => readProgress(lastCard == null ? void 0 : lastCard.response), [lastCard]);
|
|
1713
|
+
React19.useEffect(() => {
|
|
1714
|
+
var _a2;
|
|
1715
|
+
if (startedRunRef.current === runId) return;
|
|
1716
|
+
const isFirstRun = startedRunRef.current < 0;
|
|
1717
|
+
startedRunRef.current = runId;
|
|
1718
|
+
sendMessage(isFirstRun && !resumed ? startMessage : SKIP_ONE_SENTINEL);
|
|
1719
|
+
if (!isFirstRun) return;
|
|
1720
|
+
(_a2 = onEventRef.current) == null ? void 0 : _a2.call(
|
|
1680
1721
|
onEventRef,
|
|
1681
1722
|
resumed ? { type: "resumed", contextId: sessionId } : { type: "started", contextId: sessionId }
|
|
1682
1723
|
);
|
|
1683
|
-
}, [sendMessage, startMessage, resumed, sessionId]);
|
|
1684
|
-
|
|
1724
|
+
}, [sendMessage, startMessage, resumed, sessionId, runId]);
|
|
1725
|
+
React19.useEffect(() => {
|
|
1685
1726
|
if (lastCard) return;
|
|
1686
1727
|
const timer = setTimeout(() => setTimedOut(true), startTimeoutMs);
|
|
1687
1728
|
return () => clearTimeout(timer);
|
|
1688
|
-
}, [lastCard, startTimeoutMs]);
|
|
1689
|
-
|
|
1690
|
-
var
|
|
1729
|
+
}, [lastCard, startTimeoutMs, runId]);
|
|
1730
|
+
React19.useEffect(() => {
|
|
1731
|
+
var _a2, _b2, _c2, _d2;
|
|
1691
1732
|
setValidationError(void 0);
|
|
1692
1733
|
if (!(lastCard == null ? void 0 : lastCard.id)) return;
|
|
1693
|
-
const step2 = (
|
|
1734
|
+
const step2 = (_a2 = progress.step) != null ? _a2 : renderedCount;
|
|
1694
1735
|
lastScreenIndexRef.current = Math.max(0, step2 - 1);
|
|
1695
1736
|
(_c2 = onEventRef.current) == null ? void 0 : _c2.call(onEventRef, {
|
|
1696
1737
|
type: "turn",
|
|
@@ -1704,33 +1745,33 @@ var OnboardingFlow = ({
|
|
|
1704
1745
|
});
|
|
1705
1746
|
}
|
|
1706
1747
|
}, [lastCard == null ? void 0 : lastCard.id]);
|
|
1707
|
-
|
|
1748
|
+
React19.useEffect(() => {
|
|
1708
1749
|
return () => {
|
|
1709
|
-
var
|
|
1750
|
+
var _a2, _b2, _c2;
|
|
1710
1751
|
if (finished.current || degradedRef.current) return;
|
|
1711
1752
|
reportClientEvent(reportTargetRef.current, {
|
|
1712
1753
|
event_type: "dropped",
|
|
1713
1754
|
session_id: sessionIdRef.current,
|
|
1714
1755
|
screen_index: lastScreenIndexRef.current >= 0 ? lastScreenIndexRef.current : void 0,
|
|
1715
|
-
device: (
|
|
1756
|
+
device: (_a2 = clientContextRef.current) == null ? void 0 : _a2.device,
|
|
1716
1757
|
user_context: (_b2 = clientContextRef.current) == null ? void 0 : _b2.userContext,
|
|
1717
1758
|
user_id: (_c2 = clientContextRef.current) == null ? void 0 : _c2.userId
|
|
1718
1759
|
});
|
|
1719
1760
|
};
|
|
1720
1761
|
}, []);
|
|
1721
|
-
const restartThread =
|
|
1762
|
+
const restartThread = React19.useCallback(() => {
|
|
1722
1763
|
setTimedOut(false);
|
|
1723
|
-
started.current = false;
|
|
1724
1764
|
errored.current = false;
|
|
1765
|
+
setRunId((n) => n + 1);
|
|
1725
1766
|
reset();
|
|
1726
1767
|
}, [reset]);
|
|
1727
|
-
|
|
1728
|
-
var
|
|
1768
|
+
React19.useEffect(() => {
|
|
1769
|
+
var _a2, _b2, _c2, _d2, _e2, _f2, _g;
|
|
1729
1770
|
if (errored.current) return;
|
|
1730
1771
|
if (!error && !timedOut) return;
|
|
1731
1772
|
errored.current = true;
|
|
1732
1773
|
const reason = error ? "backend" : "timeout";
|
|
1733
|
-
(
|
|
1774
|
+
(_a2 = onEventRef.current) == null ? void 0 : _a2.call(onEventRef, { type: "error", reason });
|
|
1734
1775
|
attempts.current += 1;
|
|
1735
1776
|
if (attempts.current <= maxRetries) {
|
|
1736
1777
|
(_b2 = onEventRef.current) == null ? void 0 : _b2.call(onEventRef, { type: "retry", reason, attempt: attempts.current });
|
|
@@ -1751,22 +1792,52 @@ var OnboardingFlow = ({
|
|
|
1751
1792
|
(_g = onErrorRef.current) == null ? void 0 : _g.call(onErrorRef, error != null ? error : new Error("Onboarding timed out"));
|
|
1752
1793
|
}
|
|
1753
1794
|
}, [error, timedOut, maxRetries]);
|
|
1754
|
-
const handleFinish =
|
|
1795
|
+
const handleFinish = React19.useCallback(() => {
|
|
1755
1796
|
if (finished.current) return;
|
|
1756
1797
|
finished.current = true;
|
|
1757
1798
|
onCompleteRef.current({ answers: deriveAnswers(messages), raw: messages });
|
|
1758
1799
|
}, [messages]);
|
|
1759
|
-
const handleRetry =
|
|
1800
|
+
const handleRetry = React19.useCallback(() => {
|
|
1760
1801
|
attempts.current = 0;
|
|
1761
1802
|
degradedRef.current = false;
|
|
1762
1803
|
setDegraded(false);
|
|
1763
1804
|
restartThread();
|
|
1764
1805
|
}, [restartThread]);
|
|
1765
|
-
const skipQuestion =
|
|
1806
|
+
const skipQuestion = React19.useCallback(() => {
|
|
1766
1807
|
if (isLoading) return;
|
|
1767
1808
|
sendMessage(SKIP_ONE_SENTINEL);
|
|
1768
1809
|
}, [isLoading, sendMessage]);
|
|
1769
|
-
const
|
|
1810
|
+
const emitPermissionStage = React19.useCallback(
|
|
1811
|
+
(permission, stage, status) => {
|
|
1812
|
+
var _a2, _b2, _c2, _d2;
|
|
1813
|
+
(_a2 = onEventRef.current) == null ? void 0 : _a2.call(onEventRef, { type: "permission", permission, stage, status });
|
|
1814
|
+
reportClientEvent(reportTargetRef.current, {
|
|
1815
|
+
event_type: "app_event",
|
|
1816
|
+
session_id: sessionIdRef.current,
|
|
1817
|
+
question_key: permissionEventName(stage),
|
|
1818
|
+
component: PERMISSION_CARD_NAME,
|
|
1819
|
+
screen_index: lastScreenIndexRef.current >= 0 ? lastScreenIndexRef.current : void 0,
|
|
1820
|
+
meta: JSON.stringify(permissionEventProps(permission, status)),
|
|
1821
|
+
device: (_b2 = clientContextRef.current) == null ? void 0 : _b2.device,
|
|
1822
|
+
user_context: (_c2 = clientContextRef.current) == null ? void 0 : _c2.userContext,
|
|
1823
|
+
user_id: (_d2 = clientContextRef.current) == null ? void 0 : _d2.userId
|
|
1824
|
+
});
|
|
1825
|
+
},
|
|
1826
|
+
[]
|
|
1827
|
+
);
|
|
1828
|
+
const settlePermission = React19.useCallback(
|
|
1829
|
+
(id, screen, outcome) => {
|
|
1830
|
+
var _a2, _b2;
|
|
1831
|
+
setLocallySettledPermissions((prev) => prev.includes(id) ? prev : [...prev, id]);
|
|
1832
|
+
(_a2 = onPermissionSettledRef.current) == null ? void 0 : _a2.call(onPermissionSettledRef, id, outcome);
|
|
1833
|
+
try {
|
|
1834
|
+
(_b2 = screen.onResult) == null ? void 0 : _b2.call(screen, screen.permission, outcome);
|
|
1835
|
+
} catch {
|
|
1836
|
+
}
|
|
1837
|
+
},
|
|
1838
|
+
[]
|
|
1839
|
+
);
|
|
1840
|
+
const previewOnSelect = React19.useCallback((value) => {
|
|
1770
1841
|
const target = reportTargetRef.current;
|
|
1771
1842
|
if (!(target == null ? void 0 : target.serverUrl)) return;
|
|
1772
1843
|
if (Array.isArray(value) ? value.length === 0 : !value) return;
|
|
@@ -1778,31 +1849,31 @@ var OnboardingFlow = ({
|
|
|
1778
1849
|
});
|
|
1779
1850
|
}, 300);
|
|
1780
1851
|
}, []);
|
|
1781
|
-
|
|
1852
|
+
React19.useEffect(() => () => {
|
|
1782
1853
|
if (previewTimer.current) clearTimeout(previewTimer.current);
|
|
1783
1854
|
}, []);
|
|
1784
|
-
const wrappedActions =
|
|
1855
|
+
const wrappedActions = React19.useCallback(
|
|
1785
1856
|
(messageId) => {
|
|
1786
|
-
var
|
|
1857
|
+
var _a2;
|
|
1787
1858
|
const base = makeActions(messageId);
|
|
1788
1859
|
const validators2 = validatorsRef.current;
|
|
1789
|
-
const validator = (
|
|
1860
|
+
const validator = (_a2 = progress.slot_id ? validators2 == null ? void 0 : validators2[progress.slot_id] : void 0) != null ? _a2 : progress.key ? validators2 == null ? void 0 : validators2[progress.key] : void 0;
|
|
1790
1861
|
if (!validator) return base;
|
|
1791
1862
|
const out = { ...base };
|
|
1792
|
-
for (const
|
|
1793
|
-
const original = base[
|
|
1863
|
+
for (const name of ANSWER_CALLBACKS) {
|
|
1864
|
+
const original = base[name];
|
|
1794
1865
|
if (!original) continue;
|
|
1795
|
-
out[
|
|
1866
|
+
out[name] = (...args) => {
|
|
1796
1867
|
const value = args[0];
|
|
1797
1868
|
if (typeof value !== "string") return original(...args);
|
|
1798
1869
|
setValidating(true);
|
|
1799
1870
|
validator(value).then((res) => {
|
|
1800
|
-
var
|
|
1871
|
+
var _a3;
|
|
1801
1872
|
if (res.ok) {
|
|
1802
1873
|
setValidationError(void 0);
|
|
1803
1874
|
original(...args);
|
|
1804
1875
|
} else {
|
|
1805
|
-
setValidationError((
|
|
1876
|
+
setValidationError((_a3 = res.error) != null ? _a3 : "That value isn't available.");
|
|
1806
1877
|
}
|
|
1807
1878
|
}).catch(() => {
|
|
1808
1879
|
original(...args);
|
|
@@ -1833,9 +1904,39 @@ var OnboardingFlow = ({
|
|
|
1833
1904
|
if (!lastCard || !response) {
|
|
1834
1905
|
return /* @__PURE__ */ jsxRuntime.jsx(LoadingScreen, { title: c.startingTitle, hint: c.startingHint });
|
|
1835
1906
|
}
|
|
1836
|
-
const step = (
|
|
1907
|
+
const step = (_a = progress.step) != null ? _a : renderedCount;
|
|
1837
1908
|
const total = (_b = progress.total) != null ? _b : approxScreens;
|
|
1838
1909
|
const isTerminal = response.action === "render" && response.component === "StatusCard";
|
|
1910
|
+
const duePermission = permissionsPending ? void 0 : selectDuePermissionScreen(
|
|
1911
|
+
permissionScreens,
|
|
1912
|
+
settledPermissions ? [...settledPermissions, ...locallySettledPermissions] : locallySettledPermissions,
|
|
1913
|
+
{ cardIndex: renderedCount - 1, isTerminal }
|
|
1914
|
+
);
|
|
1915
|
+
if (duePermission) {
|
|
1916
|
+
const { screen, id } = duePermission;
|
|
1917
|
+
const copy2 = resolvePermissionCopy(screen.permission, screen.copy);
|
|
1918
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OnboardingScaffold, { step, approxScreens: total, children: /* @__PURE__ */ jsxRuntime.jsx(CardHandoff, { transitionKey: `permission:${id}`, variant: "spring", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1919
|
+
PermissionCardView,
|
|
1920
|
+
{
|
|
1921
|
+
permission: screen.permission,
|
|
1922
|
+
title: copy2.title,
|
|
1923
|
+
message: copy2.message,
|
|
1924
|
+
primaryLabel: copy2.primaryLabel,
|
|
1925
|
+
secondaryLabel: copy2.secondaryLabel,
|
|
1926
|
+
blockedTitle: copy2.blockedTitle,
|
|
1927
|
+
blockedMessage: copy2.blockedMessage,
|
|
1928
|
+
settingsLabel: copy2.settingsLabel,
|
|
1929
|
+
continueLabel: copy2.continueLabel,
|
|
1930
|
+
illustration: screen.illustration,
|
|
1931
|
+
request: screen.request,
|
|
1932
|
+
getStatus: screen.getStatus,
|
|
1933
|
+
openSettings: screen.openSettings,
|
|
1934
|
+
onStage: (stage, status) => emitPermissionStage(screen.permission, stage, status),
|
|
1935
|
+
onSettled: (outcome) => settlePermission(id, screen, outcome)
|
|
1936
|
+
},
|
|
1937
|
+
id
|
|
1938
|
+
) }) });
|
|
1939
|
+
}
|
|
1839
1940
|
if (isTerminal) {
|
|
1840
1941
|
const props = (_c = response.props) != null ? _c : {};
|
|
1841
1942
|
return /* @__PURE__ */ jsxRuntime.jsx(OnboardingScaffold, { step, complete: true, approxScreens: total, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1894,8 +1995,8 @@ var OnboardingFlow = ({
|
|
|
1894
1995
|
}
|
|
1895
1996
|
);
|
|
1896
1997
|
};
|
|
1897
|
-
var
|
|
1898
|
-
var
|
|
1998
|
+
var easeWire5 = reactNative.Easing.bezier(...WIRE_BEZIER);
|
|
1999
|
+
var schema2 = zod.z.object({
|
|
1899
2000
|
title: zod.z.string().describe("Question or section header, e.g. 'Which season?'"),
|
|
1900
2001
|
chips: zod.z.array(zod.z.string()).min(1).describe("List of option labels shown as chips, e.g. ['Spring','Summer','Autumn','Winter']"),
|
|
1901
2002
|
multiSelect: zod.z.boolean().optional().describe("Allow multiple chips selected at once, default true"),
|
|
@@ -1905,9 +2006,9 @@ var schema = zod.z.object({
|
|
|
1905
2006
|
var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
1906
2007
|
const t = useOnboardingTheme();
|
|
1907
2008
|
const reduced = useReducedMotion();
|
|
1908
|
-
const handlePress =
|
|
1909
|
-
const pressScale =
|
|
1910
|
-
const pressTo =
|
|
2009
|
+
const handlePress = React19.useCallback(() => onToggle(chip), [chip, onToggle]);
|
|
2010
|
+
const pressScale = React19.useRef(new reactNative.Animated.Value(1)).current;
|
|
2011
|
+
const pressTo = React19.useCallback(
|
|
1911
2012
|
(to) => {
|
|
1912
2013
|
if (reduced) return;
|
|
1913
2014
|
reactNative.Animated.spring(pressScale, {
|
|
@@ -1919,21 +2020,21 @@ var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
|
1919
2020
|
},
|
|
1920
2021
|
[pressScale, reduced]
|
|
1921
2022
|
);
|
|
1922
|
-
const handlePressIn =
|
|
1923
|
-
const handlePressOut =
|
|
1924
|
-
const fillT =
|
|
1925
|
-
|
|
2023
|
+
const handlePressIn = React19.useCallback(() => pressTo(CHIP_PRESS_SCALE), [pressTo]);
|
|
2024
|
+
const handlePressOut = React19.useCallback(() => pressTo(1), [pressTo]);
|
|
2025
|
+
const fillT = React19.useRef(new reactNative.Animated.Value(isSelected ? 1 : 0)).current;
|
|
2026
|
+
React19.useEffect(() => {
|
|
1926
2027
|
const anim = reactNative.Animated.timing(fillT, {
|
|
1927
2028
|
toValue: isSelected ? 1 : 0,
|
|
1928
2029
|
duration: scaledMs(stateChangeDuration(reduced, CHIP_FILL_MS)),
|
|
1929
|
-
easing:
|
|
2030
|
+
easing: easeWire5,
|
|
1930
2031
|
useNativeDriver: true
|
|
1931
2032
|
});
|
|
1932
2033
|
anim.start();
|
|
1933
2034
|
return () => anim.stop();
|
|
1934
2035
|
}, [isSelected, reduced, fillT]);
|
|
1935
|
-
const checkT =
|
|
1936
|
-
|
|
2036
|
+
const checkT = React19.useRef(new reactNative.Animated.Value(isSelected ? 1 : 0)).current;
|
|
2037
|
+
React19.useEffect(() => {
|
|
1937
2038
|
if (!isSelected) {
|
|
1938
2039
|
checkT.setValue(0);
|
|
1939
2040
|
return;
|
|
@@ -1966,7 +2067,7 @@ var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
|
1966
2067
|
reactNative.Animated.View,
|
|
1967
2068
|
{
|
|
1968
2069
|
style: [
|
|
1969
|
-
|
|
2070
|
+
styles11.chip,
|
|
1970
2071
|
{
|
|
1971
2072
|
borderRadius: t.radius.full,
|
|
1972
2073
|
paddingHorizontal: t.spacing.md,
|
|
@@ -1983,7 +2084,7 @@ var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
|
1983
2084
|
pointerEvents: "none",
|
|
1984
2085
|
style: [
|
|
1985
2086
|
reactNative.StyleSheet.absoluteFill,
|
|
1986
|
-
|
|
2087
|
+
styles11.fillOverlay,
|
|
1987
2088
|
{
|
|
1988
2089
|
borderRadius: t.radius.full,
|
|
1989
2090
|
borderColor: t.colors.primary,
|
|
@@ -1997,7 +2098,7 @@ var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
|
1997
2098
|
reactNative.Animated.Text,
|
|
1998
2099
|
{
|
|
1999
2100
|
style: [
|
|
2000
|
-
|
|
2101
|
+
styles11.check,
|
|
2001
2102
|
{ color: t.colors.onPrimary, opacity: checkT, transform: [{ scale: checkScale }] }
|
|
2002
2103
|
],
|
|
2003
2104
|
children: "\u2713"
|
|
@@ -2008,7 +2109,7 @@ var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
|
2008
2109
|
{
|
|
2009
2110
|
style: [
|
|
2010
2111
|
captionStyle(t.fonts),
|
|
2011
|
-
|
|
2112
|
+
styles11.chipLabel,
|
|
2012
2113
|
{ color: isSelected ? t.colors.onPrimary : t.colors.textMuted }
|
|
2013
2114
|
],
|
|
2014
2115
|
children: chip
|
|
@@ -2020,7 +2121,7 @@ var _ChipItem = ({ chip, isSelected, multiSelect, onToggle }) => {
|
|
|
2020
2121
|
}
|
|
2021
2122
|
);
|
|
2022
2123
|
};
|
|
2023
|
-
var ChipItem =
|
|
2124
|
+
var ChipItem = React19__default.default.memo(_ChipItem);
|
|
2024
2125
|
var _ChipSelectCard = ({
|
|
2025
2126
|
title,
|
|
2026
2127
|
chips,
|
|
@@ -2031,12 +2132,12 @@ var _ChipSelectCard = ({
|
|
|
2031
2132
|
onSelectionChange
|
|
2032
2133
|
}) => {
|
|
2033
2134
|
const t = useOnboardingTheme();
|
|
2034
|
-
const [selected, setSelected] =
|
|
2035
|
-
const [submitted, setSubmitted] =
|
|
2036
|
-
|
|
2135
|
+
const [selected, setSelected] = React19.useState([]);
|
|
2136
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
2137
|
+
React19.useEffect(() => {
|
|
2037
2138
|
if (!submitted && selected.length) onSelectionChange == null ? void 0 : onSelectionChange(multiSelect ? selected : selected[0]);
|
|
2038
2139
|
}, [selected, submitted, multiSelect, onSelectionChange]);
|
|
2039
|
-
const toggle =
|
|
2140
|
+
const toggle = React19.useCallback(
|
|
2040
2141
|
(chip) => {
|
|
2041
2142
|
if (submitted) return;
|
|
2042
2143
|
if (multiSelect) {
|
|
@@ -2051,7 +2152,7 @@ var _ChipSelectCard = ({
|
|
|
2051
2152
|
},
|
|
2052
2153
|
[submitted, multiSelect, maxSelections]
|
|
2053
2154
|
);
|
|
2054
|
-
const handleSubmit =
|
|
2155
|
+
const handleSubmit = React19.useCallback(() => {
|
|
2055
2156
|
if (!selected.length || !onSelect || submitted) return;
|
|
2056
2157
|
setSubmitted(true);
|
|
2057
2158
|
onSelect(multiSelect ? selected : selected[0]);
|
|
@@ -2070,7 +2171,7 @@ var _ChipSelectCard = ({
|
|
|
2070
2171
|
disabled: selected.length === 0 || submitted
|
|
2071
2172
|
}
|
|
2072
2173
|
),
|
|
2073
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
2174
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles11.chipsRow, { gap: t.spacing.sm + t.spacing.xs }], children: chips.map((chip) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2074
2175
|
ChipItem,
|
|
2075
2176
|
{
|
|
2076
2177
|
chip,
|
|
@@ -2086,18 +2187,18 @@ var _ChipSelectCard = ({
|
|
|
2086
2187
|
var ChipSelectCard = {
|
|
2087
2188
|
name: "ChipSelectCard",
|
|
2088
2189
|
description: "Use for compact short labels: seasons, activities, travel styles, moods, categories. Ideal for 4\u201312 single-word or two-word options. Use SelectionCard instead when options need descriptions; use CardGridSelectCard for a smaller set (2\u20136) of visual choices that each deserve an icon.",
|
|
2089
|
-
component:
|
|
2090
|
-
propsSchema:
|
|
2190
|
+
component: React19__default.default.memo(_ChipSelectCard),
|
|
2191
|
+
propsSchema: schema2,
|
|
2091
2192
|
defaultProps: { multiSelect: true, submitLabel: "Continue" }
|
|
2092
2193
|
};
|
|
2093
|
-
var
|
|
2194
|
+
var styles11 = reactNative.StyleSheet.create({
|
|
2094
2195
|
chipsRow: { flexDirection: "row", flexWrap: "wrap" },
|
|
2095
2196
|
chip: { borderWidth: 1.5, flexDirection: "row", alignItems: "center", gap: 6, overflow: "hidden" },
|
|
2096
2197
|
fillOverlay: { borderWidth: 1.5 },
|
|
2097
2198
|
chipLabel: { fontWeight: "600" },
|
|
2098
2199
|
check: { fontSize: 13, fontWeight: "800", lineHeight: 15 }
|
|
2099
2200
|
});
|
|
2100
|
-
var
|
|
2201
|
+
var schema3 = zod.z.object({
|
|
2101
2202
|
label: zod.z.string().describe("Input field label / the question being asked"),
|
|
2102
2203
|
hint: zod.z.string().optional().describe(
|
|
2103
2204
|
"One short line under the question giving context: what the answer is used for or why you ask. Add it whenever the question alone might be unclear."
|
|
@@ -2122,14 +2223,14 @@ var _TextInputCard = ({
|
|
|
2122
2223
|
lines = 6
|
|
2123
2224
|
}) => {
|
|
2124
2225
|
const t = useOnboardingTheme();
|
|
2125
|
-
const
|
|
2226
|
+
const styles18 = React19.useMemo(() => makeStyles3(t), [t]);
|
|
2126
2227
|
const { height: screenHeight } = reactNative.useWindowDimensions();
|
|
2127
|
-
const [value, setValue] =
|
|
2128
|
-
const [submitted, setSubmitted] =
|
|
2228
|
+
const [value, setValue] = React19.useState("");
|
|
2229
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
2129
2230
|
const locked = submitted && !validationError;
|
|
2130
2231
|
const APPROX_ROW_HEIGHT = 26;
|
|
2131
2232
|
const minHeight = multiline ? Math.min(Math.max(lines, 4) * APPROX_ROW_HEIGHT + t.spacing.md * 2, screenHeight * 0.4) : 52;
|
|
2132
|
-
const handleSubmit =
|
|
2233
|
+
const handleSubmit = React19.useCallback(() => {
|
|
2133
2234
|
if (value.trim() && onSubmit && !locked) {
|
|
2134
2235
|
setSubmitted(true);
|
|
2135
2236
|
onSubmit(value.trim());
|
|
@@ -2149,7 +2250,7 @@ var _TextInputCard = ({
|
|
|
2149
2250
|
disabled: !value.trim() || locked
|
|
2150
2251
|
}
|
|
2151
2252
|
),
|
|
2152
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
2253
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles18.row, children: [
|
|
2153
2254
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2154
2255
|
reactNative.TextInput,
|
|
2155
2256
|
{
|
|
@@ -2163,7 +2264,7 @@ var _TextInputCard = ({
|
|
|
2163
2264
|
textAlignVertical: multiline ? "top" : "center",
|
|
2164
2265
|
style: [
|
|
2165
2266
|
bodyStyle(t.fonts),
|
|
2166
|
-
|
|
2267
|
+
styles18.input,
|
|
2167
2268
|
{
|
|
2168
2269
|
color: t.colors.text,
|
|
2169
2270
|
backgroundColor: t.colors.surface,
|
|
@@ -2183,8 +2284,8 @@ var _TextInputCard = ({
|
|
|
2183
2284
|
var TextInputCard = {
|
|
2184
2285
|
name: "TextInputCard",
|
|
2185
2286
|
description: "Use when the user needs to type a free-text answer: an open-ended goal, notes, feedback, a name, a destination, a search query. Multi-line by default (great for open-ended goals); set multiline:false for a short single-line field like a name. Use NumberStepperCard for numeric ranges with known bounds.",
|
|
2186
|
-
component:
|
|
2187
|
-
propsSchema:
|
|
2287
|
+
component: React19__default.default.memo(_TextInputCard),
|
|
2288
|
+
propsSchema: schema3,
|
|
2188
2289
|
defaultProps: { submitLabel: "Submit", multiline: true, lines: 6 }
|
|
2189
2290
|
};
|
|
2190
2291
|
function makeStyles3(t) {
|
|
@@ -2199,7 +2300,7 @@ var runtimeRequire = (moduleName) => {
|
|
|
2199
2300
|
if (moduleName !== "@expo/vector-icons") return void 0;
|
|
2200
2301
|
if (typeof __require !== "function") return void 0;
|
|
2201
2302
|
try {
|
|
2202
|
-
return
|
|
2303
|
+
return require("@expo/vector-icons");
|
|
2203
2304
|
} catch {
|
|
2204
2305
|
return void 0;
|
|
2205
2306
|
}
|
|
@@ -2328,32 +2429,32 @@ var WIRE_ICON_GLYPHS = {
|
|
|
2328
2429
|
other: { family: "MaterialCommunityIcons", name: "dots-horizontal-circle" }
|
|
2329
2430
|
};
|
|
2330
2431
|
var WIRE_ICON_NAMES = Object.keys(WIRE_ICON_GLYPHS).sort();
|
|
2331
|
-
var lookupIconGlyph = (
|
|
2332
|
-
if (!
|
|
2333
|
-
if (!Object.prototype.hasOwnProperty.call(WIRE_ICON_GLYPHS,
|
|
2334
|
-
return WIRE_ICON_GLYPHS[
|
|
2432
|
+
var lookupIconGlyph = (name) => {
|
|
2433
|
+
if (!name) return void 0;
|
|
2434
|
+
if (!Object.prototype.hasOwnProperty.call(WIRE_ICON_GLYPHS, name)) return void 0;
|
|
2435
|
+
return WIRE_ICON_GLYPHS[name];
|
|
2335
2436
|
};
|
|
2336
|
-
var _WireIcon = ({ name
|
|
2337
|
-
const hostIcon = useHostIcon(
|
|
2437
|
+
var _WireIcon = ({ name, size = 20, color, requireModule }) => {
|
|
2438
|
+
const hostIcon = useHostIcon(name);
|
|
2338
2439
|
if (hostIcon) {
|
|
2339
2440
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2340
2441
|
reactNative.View,
|
|
2341
2442
|
{
|
|
2342
|
-
style:
|
|
2443
|
+
style: styles12.decorative,
|
|
2343
2444
|
accessible: false,
|
|
2344
2445
|
importantForAccessibility: "no-hide-descendants",
|
|
2345
2446
|
children: hostIcon
|
|
2346
2447
|
}
|
|
2347
2448
|
);
|
|
2348
2449
|
}
|
|
2349
|
-
const glyph = lookupIconGlyph(
|
|
2450
|
+
const glyph = lookupIconGlyph(name);
|
|
2350
2451
|
if (!glyph) return null;
|
|
2351
2452
|
const Family = resolveIconFamily(glyph.family, requireModule);
|
|
2352
2453
|
if (!Family) return null;
|
|
2353
2454
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2354
2455
|
reactNative.View,
|
|
2355
2456
|
{
|
|
2356
|
-
style:
|
|
2457
|
+
style: styles12.decorative,
|
|
2357
2458
|
accessible: false,
|
|
2358
2459
|
importantForAccessibility: "no-hide-descendants",
|
|
2359
2460
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2368,9 +2469,9 @@ var _WireIcon = ({ name: name2, size = 20, color, requireModule }) => {
|
|
|
2368
2469
|
}
|
|
2369
2470
|
);
|
|
2370
2471
|
};
|
|
2371
|
-
var WireIcon =
|
|
2472
|
+
var WireIcon = React19__default.default.memo(_WireIcon);
|
|
2372
2473
|
WireIcon.displayName = "WireIcon";
|
|
2373
|
-
var
|
|
2474
|
+
var styles12 = reactNative.StyleSheet.create({
|
|
2374
2475
|
// No size/margin of its own: the glyph decides its footprint, so an absent icon and a
|
|
2375
2476
|
// present one differ by exactly the glyph — never by a wrapper.
|
|
2376
2477
|
decorative: {}
|
|
@@ -2384,8 +2485,8 @@ var optionObjectSchema = zod.z.object({
|
|
|
2384
2485
|
var coerceOptions = (arr) => Array.isArray(arr) ? arr.map((item) => typeof item === "string" ? { value: item, label: item } : item) : arr;
|
|
2385
2486
|
var optionsField = (description) => zod.z.preprocess(coerceOptions, zod.z.array(optionObjectSchema).min(1)).describe(description);
|
|
2386
2487
|
var normalizeOptions = (options) => options.map((opt) => typeof opt === "string" ? { value: opt, label: opt } : opt);
|
|
2387
|
-
var
|
|
2388
|
-
var
|
|
2488
|
+
var easeWire6 = reactNative.Easing.bezier(...WIRE_BEZIER);
|
|
2489
|
+
var schema4 = zod.z.object({
|
|
2389
2490
|
title: zod.z.string().describe("Question or prompt for the user"),
|
|
2390
2491
|
options: optionsField("List of choices"),
|
|
2391
2492
|
submitLabel: zod.z.string().optional().describe("Submit button label, default: Continue"),
|
|
@@ -2394,9 +2495,9 @@ var schema3 = zod.z.object({
|
|
|
2394
2495
|
var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
2395
2496
|
const t = useOnboardingTheme();
|
|
2396
2497
|
const reduced = useReducedMotion();
|
|
2397
|
-
const handlePress =
|
|
2398
|
-
const pressScale =
|
|
2399
|
-
const pressTo =
|
|
2498
|
+
const handlePress = React19.useCallback(() => onToggle(opt.value), [opt.value, onToggle]);
|
|
2499
|
+
const pressScale = React19.useRef(new reactNative.Animated.Value(1)).current;
|
|
2500
|
+
const pressTo = React19.useCallback(
|
|
2400
2501
|
(to) => {
|
|
2401
2502
|
if (reduced) return;
|
|
2402
2503
|
reactNative.Animated.spring(pressScale, {
|
|
@@ -2408,21 +2509,21 @@ var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2408
2509
|
},
|
|
2409
2510
|
[pressScale, reduced]
|
|
2410
2511
|
);
|
|
2411
|
-
const handlePressIn =
|
|
2412
|
-
const handlePressOut =
|
|
2413
|
-
const selectT =
|
|
2414
|
-
|
|
2512
|
+
const handlePressIn = React19.useCallback(() => pressTo(ROW_PRESS_SCALE), [pressTo]);
|
|
2513
|
+
const handlePressOut = React19.useCallback(() => pressTo(1), [pressTo]);
|
|
2514
|
+
const selectT = React19.useRef(new reactNative.Animated.Value(isSelected ? 1 : 0)).current;
|
|
2515
|
+
React19.useEffect(() => {
|
|
2415
2516
|
const anim = reactNative.Animated.timing(selectT, {
|
|
2416
2517
|
toValue: isSelected ? 1 : 0,
|
|
2417
2518
|
duration: scaledMs(stateChangeDuration(reduced, SELECT_FILL_MS)),
|
|
2418
|
-
easing:
|
|
2519
|
+
easing: easeWire6,
|
|
2419
2520
|
useNativeDriver: true
|
|
2420
2521
|
});
|
|
2421
2522
|
anim.start();
|
|
2422
2523
|
return () => anim.stop();
|
|
2423
2524
|
}, [isSelected, reduced, selectT]);
|
|
2424
|
-
const checkT =
|
|
2425
|
-
|
|
2525
|
+
const checkT = React19.useRef(new reactNative.Animated.Value(isSelected ? 1 : 0)).current;
|
|
2526
|
+
React19.useEffect(() => {
|
|
2426
2527
|
if (!isSelected) {
|
|
2427
2528
|
checkT.setValue(0);
|
|
2428
2529
|
return;
|
|
@@ -2455,7 +2556,7 @@ var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2455
2556
|
reactNative.Animated.View,
|
|
2456
2557
|
{
|
|
2457
2558
|
style: [
|
|
2458
|
-
|
|
2559
|
+
styles13.option,
|
|
2459
2560
|
{
|
|
2460
2561
|
padding: t.spacing.md,
|
|
2461
2562
|
borderRadius: t.radius.md,
|
|
@@ -2472,7 +2573,7 @@ var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2472
2573
|
pointerEvents: "none",
|
|
2473
2574
|
style: [
|
|
2474
2575
|
reactNative.StyleSheet.absoluteFill,
|
|
2475
|
-
|
|
2576
|
+
styles13.selectedOverlay,
|
|
2476
2577
|
{
|
|
2477
2578
|
borderRadius: t.radius.md,
|
|
2478
2579
|
borderColor: t.colors.primary,
|
|
@@ -2486,7 +2587,7 @@ var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2486
2587
|
reactNative.View,
|
|
2487
2588
|
{
|
|
2488
2589
|
style: [
|
|
2489
|
-
|
|
2590
|
+
styles13.indicator,
|
|
2490
2591
|
{ borderRadius: t.radius.full },
|
|
2491
2592
|
isSelected ? { borderColor: t.colors.primary, backgroundColor: t.colors.primary } : { borderColor: t.colors.borderStrong, backgroundColor: "transparent" }
|
|
2492
2593
|
],
|
|
@@ -2494,7 +2595,7 @@ var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2494
2595
|
reactNative.Animated.Text,
|
|
2495
2596
|
{
|
|
2496
2597
|
style: [
|
|
2497
|
-
|
|
2598
|
+
styles13.check,
|
|
2498
2599
|
{ color: t.colors.onPrimary, opacity: checkT, transform: [{ scale: checkScale }] }
|
|
2499
2600
|
],
|
|
2500
2601
|
children: "\u2713"
|
|
@@ -2510,7 +2611,7 @@ var _OptionRow = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2510
2611
|
}
|
|
2511
2612
|
);
|
|
2512
2613
|
};
|
|
2513
|
-
var OptionRow =
|
|
2614
|
+
var OptionRow = React19__default.default.memo(_OptionRow);
|
|
2514
2615
|
var _SelectionCard = ({
|
|
2515
2616
|
title,
|
|
2516
2617
|
options,
|
|
@@ -2520,13 +2621,13 @@ var _SelectionCard = ({
|
|
|
2520
2621
|
onSelectionChange
|
|
2521
2622
|
}) => {
|
|
2522
2623
|
const t = useOnboardingTheme();
|
|
2523
|
-
const opts =
|
|
2524
|
-
const [selected, setSelected] =
|
|
2525
|
-
const [submitted, setSubmitted] =
|
|
2526
|
-
|
|
2624
|
+
const opts = React19__default.default.useMemo(() => normalizeOptions(options), [options]);
|
|
2625
|
+
const [selected, setSelected] = React19.useState([]);
|
|
2626
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
2627
|
+
React19.useEffect(() => {
|
|
2527
2628
|
if (!submitted && selected.length) onSelectionChange == null ? void 0 : onSelectionChange(multiSelect ? selected : selected[0]);
|
|
2528
2629
|
}, [selected, submitted, multiSelect, onSelectionChange]);
|
|
2529
|
-
const toggle =
|
|
2630
|
+
const toggle = React19.useCallback(
|
|
2530
2631
|
(value) => {
|
|
2531
2632
|
if (submitted) return;
|
|
2532
2633
|
if (multiSelect) {
|
|
@@ -2537,7 +2638,7 @@ var _SelectionCard = ({
|
|
|
2537
2638
|
},
|
|
2538
2639
|
[submitted, multiSelect]
|
|
2539
2640
|
);
|
|
2540
|
-
const handleSubmit =
|
|
2641
|
+
const handleSubmit = React19.useCallback(() => {
|
|
2541
2642
|
if (!selected.length || !onSelect || submitted) return;
|
|
2542
2643
|
setSubmitted(true);
|
|
2543
2644
|
onSelect(multiSelect ? selected : selected[0]);
|
|
@@ -2571,18 +2672,18 @@ var _SelectionCard = ({
|
|
|
2571
2672
|
var SelectionCard = {
|
|
2572
2673
|
name: "SelectionCard",
|
|
2573
2674
|
description: "Use for mutually exclusive (radio) or multi-select (checkbox) choices from 2\u20138 options, as a vertical list of rows. Best when options are wordy or need reading. Options may carry an optional `icon` from the vocabulary to make the list scannable. Use ChipSelectCard instead when options are short single words; use CardGridSelectCard when the options are visual and each has an obvious icon (occasions, channels, categories).",
|
|
2574
|
-
component:
|
|
2575
|
-
propsSchema:
|
|
2675
|
+
component: React19__default.default.memo(_SelectionCard),
|
|
2676
|
+
propsSchema: schema4,
|
|
2576
2677
|
defaultProps: { submitLabel: "Continue", multiSelect: false }
|
|
2577
2678
|
};
|
|
2578
|
-
var
|
|
2679
|
+
var styles13 = reactNative.StyleSheet.create({
|
|
2579
2680
|
option: { borderWidth: 1.5, flexDirection: "row", alignItems: "center", overflow: "hidden" },
|
|
2580
2681
|
selectedOverlay: { borderWidth: 1.5 },
|
|
2581
2682
|
indicator: { width: 24, height: 24, borderWidth: 2, alignItems: "center", justifyContent: "center" },
|
|
2582
2683
|
check: { fontSize: 13, fontWeight: "800", lineHeight: 15 }
|
|
2583
2684
|
});
|
|
2584
|
-
var
|
|
2585
|
-
var
|
|
2685
|
+
var easeWire7 = reactNative.Easing.bezier(...WIRE_BEZIER);
|
|
2686
|
+
var schema5 = zod.z.object({
|
|
2586
2687
|
title: zod.z.string().describe("Question or prompt for the user, e.g. 'What brings you here?'"),
|
|
2587
2688
|
options: optionsField(
|
|
2588
2689
|
"The choices, 2-6 of them. Give EVERY option an `icon` from the vocabulary \u2014 the icon is the point of this card, and an option without one renders as a bare label next to icon-bearing neighbours. Keep labels short (1-3 words) so they fit a half-width card."
|
|
@@ -2593,9 +2694,9 @@ var schema4 = zod.z.object({
|
|
|
2593
2694
|
var _OptionCard = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
2594
2695
|
const t = useOnboardingTheme();
|
|
2595
2696
|
const reduced = useReducedMotion();
|
|
2596
|
-
const handlePress =
|
|
2597
|
-
const pressScale =
|
|
2598
|
-
const pressTo =
|
|
2697
|
+
const handlePress = React19.useCallback(() => onToggle(opt.value), [opt.value, onToggle]);
|
|
2698
|
+
const pressScale = React19.useRef(new reactNative.Animated.Value(1)).current;
|
|
2699
|
+
const pressTo = React19.useCallback(
|
|
2599
2700
|
(to) => {
|
|
2600
2701
|
if (reduced) return;
|
|
2601
2702
|
reactNative.Animated.spring(pressScale, {
|
|
@@ -2607,14 +2708,14 @@ var _OptionCard = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2607
2708
|
},
|
|
2608
2709
|
[pressScale, reduced]
|
|
2609
2710
|
);
|
|
2610
|
-
const handlePressIn =
|
|
2611
|
-
const handlePressOut =
|
|
2612
|
-
const selectT =
|
|
2613
|
-
|
|
2711
|
+
const handlePressIn = React19.useCallback(() => pressTo(ROW_PRESS_SCALE), [pressTo]);
|
|
2712
|
+
const handlePressOut = React19.useCallback(() => pressTo(1), [pressTo]);
|
|
2713
|
+
const selectT = React19.useRef(new reactNative.Animated.Value(isSelected ? 1 : 0)).current;
|
|
2714
|
+
React19.useEffect(() => {
|
|
2614
2715
|
const anim = reactNative.Animated.timing(selectT, {
|
|
2615
2716
|
toValue: isSelected ? 1 : 0,
|
|
2616
2717
|
duration: scaledMs(stateChangeDuration(reduced, SELECT_FILL_MS)),
|
|
2617
|
-
easing:
|
|
2718
|
+
easing: easeWire7,
|
|
2618
2719
|
useNativeDriver: true
|
|
2619
2720
|
});
|
|
2620
2721
|
anim.start();
|
|
@@ -2629,12 +2730,12 @@ var _OptionCard = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2629
2730
|
accessibilityRole: multiSelect ? "checkbox" : "radio",
|
|
2630
2731
|
accessibilityState: multiSelect ? { checked: isSelected } : { selected: isSelected },
|
|
2631
2732
|
accessibilityLabel: opt.label,
|
|
2632
|
-
style:
|
|
2733
|
+
style: styles14.cell,
|
|
2633
2734
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2634
2735
|
reactNative.Animated.View,
|
|
2635
2736
|
{
|
|
2636
2737
|
style: [
|
|
2637
|
-
|
|
2738
|
+
styles14.card,
|
|
2638
2739
|
{
|
|
2639
2740
|
padding: t.spacing.md,
|
|
2640
2741
|
borderRadius: t.radius.lg,
|
|
@@ -2651,7 +2752,7 @@ var _OptionCard = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2651
2752
|
pointerEvents: "none",
|
|
2652
2753
|
style: [
|
|
2653
2754
|
reactNative.StyleSheet.absoluteFill,
|
|
2654
|
-
|
|
2755
|
+
styles14.selectedOverlay,
|
|
2655
2756
|
{
|
|
2656
2757
|
borderRadius: t.radius.lg,
|
|
2657
2758
|
borderColor: t.colors.primary,
|
|
@@ -2669,7 +2770,7 @@ var _OptionCard = ({ opt, isSelected, multiSelect, onToggle }) => {
|
|
|
2669
2770
|
}
|
|
2670
2771
|
);
|
|
2671
2772
|
};
|
|
2672
|
-
var OptionCard =
|
|
2773
|
+
var OptionCard = React19__default.default.memo(_OptionCard);
|
|
2673
2774
|
var _CardGridSelectCard = ({
|
|
2674
2775
|
title,
|
|
2675
2776
|
options,
|
|
@@ -2679,13 +2780,13 @@ var _CardGridSelectCard = ({
|
|
|
2679
2780
|
onSelectionChange
|
|
2680
2781
|
}) => {
|
|
2681
2782
|
const t = useOnboardingTheme();
|
|
2682
|
-
const opts =
|
|
2683
|
-
const [selected, setSelected] =
|
|
2684
|
-
const [submitted, setSubmitted] =
|
|
2685
|
-
|
|
2783
|
+
const opts = React19__default.default.useMemo(() => normalizeOptions(options), [options]);
|
|
2784
|
+
const [selected, setSelected] = React19.useState([]);
|
|
2785
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
2786
|
+
React19.useEffect(() => {
|
|
2686
2787
|
if (!submitted && selected.length) onSelectionChange == null ? void 0 : onSelectionChange(multiSelect ? selected : selected[0]);
|
|
2687
2788
|
}, [selected, submitted, multiSelect, onSelectionChange]);
|
|
2688
|
-
const toggle =
|
|
2789
|
+
const toggle = React19.useCallback(
|
|
2689
2790
|
(value) => {
|
|
2690
2791
|
if (submitted) return;
|
|
2691
2792
|
if (multiSelect) {
|
|
@@ -2698,7 +2799,7 @@ var _CardGridSelectCard = ({
|
|
|
2698
2799
|
},
|
|
2699
2800
|
[submitted, multiSelect]
|
|
2700
2801
|
);
|
|
2701
|
-
const handleSubmit =
|
|
2802
|
+
const handleSubmit = React19.useCallback(() => {
|
|
2702
2803
|
if (!selected.length || !onSelect || submitted) return;
|
|
2703
2804
|
setSubmitted(true);
|
|
2704
2805
|
onSelect(multiSelect ? selected : selected[0]);
|
|
@@ -2716,7 +2817,7 @@ var _CardGridSelectCard = ({
|
|
|
2716
2817
|
disabled: selected.length === 0 || submitted
|
|
2717
2818
|
}
|
|
2718
2819
|
),
|
|
2719
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
2820
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles14.grid, { gap: t.spacing.sm }], children: opts.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2720
2821
|
OptionCard,
|
|
2721
2822
|
{
|
|
2722
2823
|
opt,
|
|
@@ -2732,19 +2833,19 @@ var _CardGridSelectCard = ({
|
|
|
2732
2833
|
var CardGridSelectCard = {
|
|
2733
2834
|
name: "CardGridSelectCard",
|
|
2734
2835
|
description: "Use for VISUAL, icon-led choices shown as a 2-column grid of tappable cards (icon on top, short label beneath). Ideal for 2\u20136 concrete options that each have an obvious icon \u2014 occasions, channels, goals, categories \u2014 e.g. 'What brings you here?' or 'Where did you hear about us?'. Multi-select by default. Every option should carry an `icon`. Use SelectionCard instead when options need descriptions or have no natural icon; use ChipSelectCard for many short word-like tags.",
|
|
2735
|
-
component:
|
|
2736
|
-
propsSchema:
|
|
2836
|
+
component: React19__default.default.memo(_CardGridSelectCard),
|
|
2837
|
+
propsSchema: schema5,
|
|
2737
2838
|
defaultProps: { submitLabel: "Continue", multiSelect: true }
|
|
2738
2839
|
};
|
|
2739
|
-
var
|
|
2840
|
+
var styles14 = reactNative.StyleSheet.create({
|
|
2740
2841
|
grid: { flexDirection: "row", flexWrap: "wrap" },
|
|
2741
2842
|
// Two per row: ~47% basis leaves room for the gap, flexGrow fills the remainder exactly.
|
|
2742
2843
|
cell: { flexBasis: "47%", flexGrow: 1 },
|
|
2743
2844
|
card: { borderWidth: 1.5, alignItems: "flex-start", overflow: "hidden" },
|
|
2744
2845
|
selectedOverlay: { borderWidth: 1.5 }
|
|
2745
2846
|
});
|
|
2746
|
-
var
|
|
2747
|
-
var
|
|
2847
|
+
var easeWire8 = reactNative.Easing.bezier(...WIRE_BEZIER);
|
|
2848
|
+
var schema6 = zod.z.object({
|
|
2748
2849
|
status: zod.z.enum(["success", "warning", "error", "info"]).describe("Status type"),
|
|
2749
2850
|
title: zod.z.string().describe("Status title"),
|
|
2750
2851
|
message: zod.z.string().optional().describe("Supporting message"),
|
|
@@ -2759,11 +2860,11 @@ var STATUS_ICONS = {
|
|
|
2759
2860
|
info: "\u2139"
|
|
2760
2861
|
};
|
|
2761
2862
|
var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSubmit }) => {
|
|
2762
|
-
var
|
|
2863
|
+
var _a;
|
|
2763
2864
|
const t = useOnboardingTheme();
|
|
2764
2865
|
const reduced = useReducedMotion();
|
|
2765
|
-
const [submitted, setSubmitted] =
|
|
2766
|
-
const color =
|
|
2866
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
2867
|
+
const color = React19.useMemo(() => {
|
|
2767
2868
|
switch (status) {
|
|
2768
2869
|
case "success":
|
|
2769
2870
|
return t.colors.success;
|
|
@@ -2775,9 +2876,9 @@ var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSu
|
|
|
2775
2876
|
return t.colors.info;
|
|
2776
2877
|
}
|
|
2777
2878
|
}, [status, t.colors]);
|
|
2778
|
-
const popT =
|
|
2779
|
-
const copyT =
|
|
2780
|
-
|
|
2879
|
+
const popT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
2880
|
+
const copyT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
2881
|
+
React19.useEffect(() => {
|
|
2781
2882
|
if (reduced) {
|
|
2782
2883
|
popT.setValue(1);
|
|
2783
2884
|
copyT.setValue(1);
|
|
@@ -2794,7 +2895,7 @@ var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSu
|
|
|
2794
2895
|
toValue: 1,
|
|
2795
2896
|
duration: scaledMs(STATUS_COPY_MS),
|
|
2796
2897
|
delay: scaledMs(STATUS_COPY_STAGGER_MS),
|
|
2797
|
-
easing:
|
|
2898
|
+
easing: easeWire8,
|
|
2798
2899
|
useNativeDriver: true
|
|
2799
2900
|
})
|
|
2800
2901
|
];
|
|
@@ -2803,7 +2904,7 @@ var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSu
|
|
|
2803
2904
|
}, [reduced, popT, copyT]);
|
|
2804
2905
|
const popScale = popT.interpolate({ inputRange: [0, 1], outputRange: [STATUS_POP_SCALE_FROM, 1] });
|
|
2805
2906
|
const copyRise = copyT.interpolate({ inputRange: [0, 1], outputRange: [10, 0] });
|
|
2806
|
-
const handleContinue =
|
|
2907
|
+
const handleContinue = React19.useCallback(() => {
|
|
2807
2908
|
if (!submitted) {
|
|
2808
2909
|
setSubmitted(true);
|
|
2809
2910
|
if (onContinue) onContinue();
|
|
@@ -2816,8 +2917,8 @@ var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSu
|
|
|
2816
2917
|
{
|
|
2817
2918
|
align: "center",
|
|
2818
2919
|
footer: ctaLabel ? /* @__PURE__ */ jsxRuntime.jsx(Button, { title: ctaLabel, onPress: handleContinue, variant: "primary", disabled: submitted }) : void 0,
|
|
2819
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
2820
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
2920
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles15.center, { gap: t.spacing.sm }], children: [
|
|
2921
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles15.titleRow, { gap: t.spacing.sm }], children: [
|
|
2821
2922
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2822
2923
|
reactNative.Animated.Text,
|
|
2823
2924
|
{
|
|
@@ -2825,7 +2926,7 @@ var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSu
|
|
|
2825
2926
|
headingStyle(t.fonts),
|
|
2826
2927
|
{ color, opacity: popT, transform: [{ scale: popScale }] }
|
|
2827
2928
|
],
|
|
2828
|
-
children: (
|
|
2929
|
+
children: (_a = STATUS_ICONS[status]) != null ? _a : "\xB7"
|
|
2829
2930
|
}
|
|
2830
2931
|
),
|
|
2831
2932
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2861,14 +2962,14 @@ var _StatusCard = ({ status, title, message, ctaLabel, onContinue, onPress, onSu
|
|
|
2861
2962
|
var StatusCard = {
|
|
2862
2963
|
name: "StatusCard",
|
|
2863
2964
|
description: "Use ONLY for real outcomes: booking confirmed, data saved, action completed. NEVER for 'you just viewed X' acknowledgments. Always include ctaLabel so the user can continue after seeing the status.",
|
|
2864
|
-
component:
|
|
2865
|
-
propsSchema:
|
|
2965
|
+
component: React19__default.default.memo(_StatusCard),
|
|
2966
|
+
propsSchema: schema6
|
|
2866
2967
|
};
|
|
2867
|
-
var
|
|
2968
|
+
var styles15 = reactNative.StyleSheet.create({
|
|
2868
2969
|
center: { width: "100%", alignItems: "center", justifyContent: "center" },
|
|
2869
2970
|
titleRow: { flexDirection: "row", alignItems: "center", justifyContent: "center" }
|
|
2870
2971
|
});
|
|
2871
|
-
var
|
|
2972
|
+
var schema7 = zod.z.object({
|
|
2872
2973
|
label: zod.z.string().describe("What is being counted, e.g. 'Number of days' or 'Travellers'"),
|
|
2873
2974
|
min: zod.z.number().optional().describe("Minimum value, default 1"),
|
|
2874
2975
|
max: zod.z.number().optional().describe("Maximum value, default 30"),
|
|
@@ -2889,22 +2990,22 @@ var _NumberStepperCard = ({
|
|
|
2889
2990
|
onSubmit
|
|
2890
2991
|
}) => {
|
|
2891
2992
|
const t = useOnboardingTheme();
|
|
2892
|
-
const
|
|
2993
|
+
const styles18 = React19.useMemo(() => makeStyles4(t), [t]);
|
|
2893
2994
|
const safeMin = safeNum(min, 1);
|
|
2894
2995
|
const safeMaxRaw = safeNum(max, 30);
|
|
2895
2996
|
const safeMax = safeMaxRaw < safeMin ? safeMin : safeMaxRaw;
|
|
2896
2997
|
const safeStepRaw = safeNum(step, 1);
|
|
2897
2998
|
const safeStep = safeStepRaw > 0 ? safeStepRaw : 1;
|
|
2898
2999
|
const safeDefault = safeNum(defaultValue, safeMin);
|
|
2899
|
-
const [value, setValue] =
|
|
2900
|
-
const [submitted, setSubmitted] =
|
|
2901
|
-
const handleDecrement =
|
|
3000
|
+
const [value, setValue] = React19.useState(Math.min(Math.max(safeDefault, safeMin), safeMax));
|
|
3001
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
3002
|
+
const handleDecrement = React19.useCallback(() => {
|
|
2902
3003
|
if (!submitted) setValue((v) => Math.max(v - safeStep, safeMin));
|
|
2903
3004
|
}, [submitted, safeStep, safeMin]);
|
|
2904
|
-
const handleIncrement =
|
|
3005
|
+
const handleIncrement = React19.useCallback(() => {
|
|
2905
3006
|
if (!submitted) setValue((v) => Math.min(v + safeStep, safeMax));
|
|
2906
3007
|
}, [submitted, safeStep, safeMax]);
|
|
2907
|
-
const handleSubmit =
|
|
3008
|
+
const handleSubmit = React19.useCallback(() => {
|
|
2908
3009
|
if (!submitted) {
|
|
2909
3010
|
setSubmitted(true);
|
|
2910
3011
|
onSubmit == null ? void 0 : onSubmit(value);
|
|
@@ -2913,7 +3014,7 @@ var _NumberStepperCard = ({
|
|
|
2913
3014
|
const atMin = value <= safeMin;
|
|
2914
3015
|
const atMax = value >= safeMax;
|
|
2915
3016
|
const stepBtnStyle = (disabled) => [
|
|
2916
|
-
|
|
3017
|
+
styles18.stepBtn,
|
|
2917
3018
|
{ borderRadius: t.radius.full, backgroundColor: t.colors.background, borderColor: disabled ? t.colors.border : t.colors.primary }
|
|
2918
3019
|
];
|
|
2919
3020
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2922,10 +3023,10 @@ var _NumberStepperCard = ({
|
|
|
2922
3023
|
title: label,
|
|
2923
3024
|
align: "center",
|
|
2924
3025
|
footer: /* @__PURE__ */ jsxRuntime.jsx(Button, { title: submitLabel, onPress: handleSubmit, variant: "primary", disabled: submitted }),
|
|
2925
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
2926
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
3026
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles18.wrap, children: [
|
|
3027
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles18.stepper, { gap: t.spacing.lg }], children: [
|
|
2927
3028
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: atMin || submitted ? void 0 : handleDecrement, disabled: atMin || submitted, style: stepBtnStyle(atMin), children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [headingStyle(t.fonts), { color: atMin ? t.colors.textMuted : t.colors.primary }], children: "\u2212" }) }),
|
|
2928
|
-
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
3029
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles18.valueBox, children: [
|
|
2929
3030
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [headingStyle(t.fonts), { color: t.colors.primary }], children: String(value) }),
|
|
2930
3031
|
unit ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [captionStyle(t.fonts), { color: t.colors.textMuted }], children: unit }) : null
|
|
2931
3032
|
] }),
|
|
@@ -2939,8 +3040,8 @@ var _NumberStepperCard = ({
|
|
|
2939
3040
|
var NumberStepperCard = {
|
|
2940
3041
|
name: "NumberStepperCard",
|
|
2941
3042
|
description: "Use for any bounded numeric input: days, people, portions, budget tiers, ratings. Best for ranges 1\u201399. Set unit (e.g. 'days', 'people') for clarity.",
|
|
2942
|
-
component:
|
|
2943
|
-
propsSchema:
|
|
3043
|
+
component: React19__default.default.memo(_NumberStepperCard),
|
|
3044
|
+
propsSchema: schema7,
|
|
2944
3045
|
defaultProps: { min: 1, max: 30, defaultValue: 1, step: 1, submitLabel: "Confirm" }
|
|
2945
3046
|
};
|
|
2946
3047
|
function makeStyles4(t) {
|
|
@@ -2951,9 +3052,9 @@ function makeStyles4(t) {
|
|
|
2951
3052
|
valueBox: { alignItems: "center", minWidth: 80 }
|
|
2952
3053
|
});
|
|
2953
3054
|
}
|
|
2954
|
-
var
|
|
2955
|
-
var
|
|
2956
|
-
var
|
|
3055
|
+
var easeWire9 = reactNative.Easing.bezier(...WIRE_BEZIER);
|
|
3056
|
+
var RISE_PX2 = 10;
|
|
3057
|
+
var schema8 = zod.z.object({
|
|
2957
3058
|
title: zod.z.string().describe("Short, warm headline for the value/momentum moment"),
|
|
2958
3059
|
body: zod.z.string().optional().describe("One or two supporting lines that reflect the user's answers back and build momentum"),
|
|
2959
3060
|
items: zod.z.array(zod.z.string()).max(4).optional().describe(
|
|
@@ -2977,9 +3078,9 @@ var _WorkItem = ({
|
|
|
2977
3078
|
reduced
|
|
2978
3079
|
}) => {
|
|
2979
3080
|
const t = useOnboardingTheme();
|
|
2980
|
-
const rowT =
|
|
2981
|
-
const checkT =
|
|
2982
|
-
|
|
3081
|
+
const rowT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
3082
|
+
const checkT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
3083
|
+
React19.useEffect(() => {
|
|
2983
3084
|
if (reduced) {
|
|
2984
3085
|
rowT.setValue(1);
|
|
2985
3086
|
checkT.setValue(1);
|
|
@@ -2990,7 +3091,7 @@ var _WorkItem = ({
|
|
|
2990
3091
|
toValue: 1,
|
|
2991
3092
|
duration: scaledMs(INTERSTITIAL_ITEM_MS),
|
|
2992
3093
|
delay: scaledMs(interstitialItemDelay(index)),
|
|
2993
|
-
easing:
|
|
3094
|
+
easing: easeWire9,
|
|
2994
3095
|
useNativeDriver: true
|
|
2995
3096
|
}),
|
|
2996
3097
|
reactNative.Animated.spring(checkT, {
|
|
@@ -3004,7 +3105,7 @@ var _WorkItem = ({
|
|
|
3004
3105
|
anims.forEach((a) => a.start());
|
|
3005
3106
|
return () => anims.forEach((a) => a.stop());
|
|
3006
3107
|
}, [reduced, index, rowT, checkT]);
|
|
3007
|
-
const rise = rowT.interpolate({ inputRange: [0, 1], outputRange: [
|
|
3108
|
+
const rise = rowT.interpolate({ inputRange: [0, 1], outputRange: [RISE_PX2, 0] });
|
|
3008
3109
|
const checkScale = checkT.interpolate({
|
|
3009
3110
|
inputRange: [0, 1],
|
|
3010
3111
|
outputRange: [INTERSTITIAL_CHECK_SCALE_FROM, 1]
|
|
@@ -3012,20 +3113,20 @@ var _WorkItem = ({
|
|
|
3012
3113
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3013
3114
|
reactNative.Animated.View,
|
|
3014
3115
|
{
|
|
3015
|
-
style: [
|
|
3116
|
+
style: [styles16.itemRow, { gap: t.spacing.sm + t.spacing.xs, opacity: rowT, transform: [{ translateY: rise }] }],
|
|
3016
3117
|
children: [
|
|
3017
3118
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3018
3119
|
reactNative.View,
|
|
3019
3120
|
{
|
|
3020
3121
|
style: [
|
|
3021
|
-
|
|
3122
|
+
styles16.itemBadge,
|
|
3022
3123
|
{ backgroundColor: t.colors.primarySoft, borderRadius: t.radius.full }
|
|
3023
3124
|
],
|
|
3024
3125
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3025
3126
|
reactNative.Animated.Text,
|
|
3026
3127
|
{
|
|
3027
3128
|
style: [
|
|
3028
|
-
|
|
3129
|
+
styles16.itemCheck,
|
|
3029
3130
|
{ color: t.colors.primary, opacity: checkT, transform: [{ scale: checkScale }] }
|
|
3030
3131
|
],
|
|
3031
3132
|
children: "\u2713"
|
|
@@ -3033,12 +3134,12 @@ var _WorkItem = ({
|
|
|
3033
3134
|
)
|
|
3034
3135
|
}
|
|
3035
3136
|
),
|
|
3036
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [bodyStyle(t.fonts),
|
|
3137
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [bodyStyle(t.fonts), styles16.itemText, { color: t.colors.text }], children: text })
|
|
3037
3138
|
]
|
|
3038
3139
|
}
|
|
3039
3140
|
);
|
|
3040
3141
|
};
|
|
3041
|
-
var WorkItem =
|
|
3142
|
+
var WorkItem = React19__default.default.memo(_WorkItem);
|
|
3042
3143
|
var _InterstitialCard = ({
|
|
3043
3144
|
title,
|
|
3044
3145
|
body,
|
|
@@ -3054,17 +3155,17 @@ var _InterstitialCard = ({
|
|
|
3054
3155
|
const reduced = useReducedMotion();
|
|
3055
3156
|
const node = useIllustration(illustration);
|
|
3056
3157
|
const fallbackNode = useIllustration(illustrationFallback);
|
|
3057
|
-
const [submitted, setSubmitted] =
|
|
3058
|
-
const [imgFailed, setImgFailed] =
|
|
3059
|
-
const [canAdvance, setCanAdvance] =
|
|
3060
|
-
|
|
3158
|
+
const [submitted, setSubmitted] = React19.useState(false);
|
|
3159
|
+
const [imgFailed, setImgFailed] = React19.useState(false);
|
|
3160
|
+
const [canAdvance, setCanAdvance] = React19.useState(false);
|
|
3161
|
+
React19.useEffect(() => {
|
|
3061
3162
|
const timer = setTimeout(() => setCanAdvance(true), MIN_DISPLAY_MS);
|
|
3062
3163
|
return () => clearTimeout(timer);
|
|
3063
3164
|
}, []);
|
|
3064
|
-
const artT =
|
|
3065
|
-
const titleT =
|
|
3066
|
-
const bodyT =
|
|
3067
|
-
|
|
3165
|
+
const artT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
3166
|
+
const titleT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
3167
|
+
const bodyT = React19.useRef(new reactNative.Animated.Value(reduced ? 1 : 0)).current;
|
|
3168
|
+
React19.useEffect(() => {
|
|
3068
3169
|
if (reduced) {
|
|
3069
3170
|
artT.setValue(1);
|
|
3070
3171
|
titleT.setValue(1);
|
|
@@ -3075,7 +3176,7 @@ var _InterstitialCard = ({
|
|
|
3075
3176
|
toValue: 1,
|
|
3076
3177
|
duration: scaledMs(INTERSTITIAL_HEAD_MS),
|
|
3077
3178
|
delay,
|
|
3078
|
-
easing:
|
|
3179
|
+
easing: easeWire9,
|
|
3079
3180
|
useNativeDriver: true
|
|
3080
3181
|
});
|
|
3081
3182
|
const anims = [
|
|
@@ -3088,9 +3189,9 @@ var _InterstitialCard = ({
|
|
|
3088
3189
|
}, [reduced, artT, titleT, bodyT]);
|
|
3089
3190
|
const riseStyle = (value) => ({
|
|
3090
3191
|
opacity: value,
|
|
3091
|
-
transform: [{ translateY: value.interpolate({ inputRange: [0, 1], outputRange: [
|
|
3192
|
+
transform: [{ translateY: value.interpolate({ inputRange: [0, 1], outputRange: [RISE_PX2, 0] }) }]
|
|
3092
3193
|
});
|
|
3093
|
-
const handleContinue =
|
|
3194
|
+
const handleContinue = React19.useCallback(() => {
|
|
3094
3195
|
if (submitted || !canAdvance) return;
|
|
3095
3196
|
setSubmitted(true);
|
|
3096
3197
|
if (onSubmit) onSubmit("continue");
|
|
@@ -3111,18 +3212,18 @@ var _InterstitialCard = ({
|
|
|
3111
3212
|
disabled: submitted || !canAdvance
|
|
3112
3213
|
}
|
|
3113
3214
|
),
|
|
3114
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [
|
|
3115
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: [
|
|
3215
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles16.center, { gap: t.spacing.md }], children: [
|
|
3216
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: [styles16.fullWidth, riseStyle(artT)], children: showImage ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3116
3217
|
reactNative.Image,
|
|
3117
3218
|
{
|
|
3118
3219
|
source: { uri: imageUrl },
|
|
3119
|
-
style:
|
|
3220
|
+
style: styles16.image,
|
|
3120
3221
|
resizeMode: "contain",
|
|
3121
3222
|
onError: () => setImgFailed(true)
|
|
3122
3223
|
}
|
|
3123
|
-
) : art ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
3224
|
+
) : art ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles16.art, children: art }) : null }),
|
|
3124
3225
|
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: riseStyle(titleT), children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [headingStyle(t.fonts), { color: t.colors.text, textAlign: "center" }], children: title }) }),
|
|
3125
|
-
(items == null ? void 0 : items.length) ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [
|
|
3226
|
+
(items == null ? void 0 : items.length) ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles16.items, { gap: t.spacing.md, marginTop: t.spacing.sm }], children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(WorkItem, { text: item, index: i, reduced }, `${item}-${i}`)) }) : body ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: riseStyle(bodyT), children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [bodyStyle(t.fonts), { color: t.colors.textMuted, textAlign: "center" }], children: body }) }) : null
|
|
3126
3227
|
] })
|
|
3127
3228
|
}
|
|
3128
3229
|
);
|
|
@@ -3130,11 +3231,11 @@ var _InterstitialCard = ({
|
|
|
3130
3231
|
var InterstitialCard = {
|
|
3131
3232
|
name: "InterstitialCard",
|
|
3132
3233
|
description: "Use ONCE mid-flow (never first, never last) as a momentum/value screen between questions \u2014 an illustration + a warm line that reflects answers back, like Duolingo/Cal-AI. NOT a question; the user just taps Continue. Set `illustration` to an app-registered artwork name. Prefer `items` (2-3 short ticked lines, each reflecting a real answer) when you have the signal. Skip it if you don't have enough signal to make the line specific.",
|
|
3133
|
-
component:
|
|
3134
|
-
propsSchema:
|
|
3234
|
+
component: React19__default.default.memo(_InterstitialCard),
|
|
3235
|
+
propsSchema: schema8,
|
|
3135
3236
|
defaultProps: { ctaLabel: "Continue", illustrationFallback: "momentum" }
|
|
3136
3237
|
};
|
|
3137
|
-
var
|
|
3238
|
+
var styles16 = reactNative.StyleSheet.create({
|
|
3138
3239
|
center: { width: "100%", alignItems: "center", justifyContent: "center" },
|
|
3139
3240
|
fullWidth: { width: "100%", alignItems: "center" },
|
|
3140
3241
|
art: { alignItems: "center", justifyContent: "center" },
|
|
@@ -3168,9 +3269,9 @@ var runtimeRequire2 = (moduleName) => {
|
|
|
3168
3269
|
try {
|
|
3169
3270
|
switch (moduleName) {
|
|
3170
3271
|
case "expo-constants":
|
|
3171
|
-
return
|
|
3272
|
+
return require("expo-constants");
|
|
3172
3273
|
case "expo-application":
|
|
3173
|
-
return
|
|
3274
|
+
return require("expo-application");
|
|
3174
3275
|
default:
|
|
3175
3276
|
return void 0;
|
|
3176
3277
|
}
|
|
@@ -3193,14 +3294,14 @@ var safeInterop = (requireModule, moduleName) => {
|
|
|
3193
3294
|
};
|
|
3194
3295
|
var detectAppVersion = (requireModule = runtimeRequire2) => {
|
|
3195
3296
|
try {
|
|
3196
|
-
const
|
|
3197
|
-
if (
|
|
3198
|
-
const expoConfig =
|
|
3297
|
+
const constants = safeInterop(requireModule, "expo-constants");
|
|
3298
|
+
if (constants) {
|
|
3299
|
+
const expoConfig = constants.expoConfig;
|
|
3199
3300
|
if (expoConfig && typeof expoConfig === "object") {
|
|
3200
3301
|
const fromExpoConfig = coerceVersion(expoConfig.version);
|
|
3201
3302
|
if (fromExpoConfig) return fromExpoConfig;
|
|
3202
3303
|
}
|
|
3203
|
-
const fromNative = coerceVersion(
|
|
3304
|
+
const fromNative = coerceVersion(constants.nativeAppVersion);
|
|
3204
3305
|
if (fromNative) return fromNative;
|
|
3205
3306
|
}
|
|
3206
3307
|
const application = safeInterop(requireModule, "expo-application");
|
|
@@ -3223,7 +3324,7 @@ var runtimeRequire3 = (moduleName) => {
|
|
|
3223
3324
|
if (moduleName !== "expo-device") return void 0;
|
|
3224
3325
|
if (typeof __require !== "function") return void 0;
|
|
3225
3326
|
try {
|
|
3226
|
-
return
|
|
3327
|
+
return require("expo-device");
|
|
3227
3328
|
} catch {
|
|
3228
3329
|
return void 0;
|
|
3229
3330
|
}
|
|
@@ -3265,7 +3366,7 @@ var deriveFormFactor = (iosIdiom, width, height) => {
|
|
|
3265
3366
|
return void 0;
|
|
3266
3367
|
};
|
|
3267
3368
|
var collectDeviceContext = () => {
|
|
3268
|
-
var
|
|
3369
|
+
var _a;
|
|
3269
3370
|
const ctx = { platform: reactNative.Platform.OS };
|
|
3270
3371
|
try {
|
|
3271
3372
|
const version = reactNative.Platform.Version;
|
|
@@ -3274,26 +3375,26 @@ var collectDeviceContext = () => {
|
|
|
3274
3375
|
}
|
|
3275
3376
|
} catch {
|
|
3276
3377
|
}
|
|
3277
|
-
let
|
|
3378
|
+
let constants = {};
|
|
3278
3379
|
try {
|
|
3279
|
-
|
|
3380
|
+
constants = (_a = reactNative.Platform.constants) != null ? _a : {};
|
|
3280
3381
|
} catch {
|
|
3281
|
-
|
|
3382
|
+
constants = {};
|
|
3282
3383
|
}
|
|
3283
3384
|
let iosIdiom;
|
|
3284
3385
|
try {
|
|
3285
3386
|
if (reactNative.Platform.OS === "android") {
|
|
3286
|
-
const brand =
|
|
3287
|
-
const model =
|
|
3288
|
-
const release =
|
|
3387
|
+
const brand = constants.Brand;
|
|
3388
|
+
const model = constants.Model;
|
|
3389
|
+
const release = constants.Release;
|
|
3289
3390
|
if (typeof brand === "string" && brand) ctx.brand = brand;
|
|
3290
3391
|
if (typeof model === "string" && model) ctx.model = model;
|
|
3291
3392
|
if (release !== void 0 && release !== null && String(release)) {
|
|
3292
3393
|
ctx.osVersion = String(release);
|
|
3293
3394
|
}
|
|
3294
3395
|
} else if (reactNative.Platform.OS === "ios") {
|
|
3295
|
-
const osVersion =
|
|
3296
|
-
const idiom =
|
|
3396
|
+
const osVersion = constants.osVersion;
|
|
3397
|
+
const idiom = constants.interfaceIdiom;
|
|
3297
3398
|
if (osVersion !== void 0 && osVersion !== null && String(osVersion)) {
|
|
3298
3399
|
ctx.osVersion = String(osVersion);
|
|
3299
3400
|
}
|
|
@@ -3344,11 +3445,11 @@ var provenanceRegistry = () => {
|
|
|
3344
3445
|
};
|
|
3345
3446
|
var provenanceKey = (space, scope) => `${space}:${scope != null ? scope : "default"}`;
|
|
3346
3447
|
var resolveIdentity = (input) => {
|
|
3347
|
-
var
|
|
3448
|
+
var _a;
|
|
3348
3449
|
if (typeof input.value !== "string") return void 0;
|
|
3349
3450
|
const value = input.value.trim();
|
|
3350
3451
|
if (!value) return void 0;
|
|
3351
|
-
const durable = (
|
|
3452
|
+
const durable = (_a = input.durable) != null ? _a : input.source === "host";
|
|
3352
3453
|
if (input.source === "host") {
|
|
3353
3454
|
provenanceRegistry().host.set(provenanceKey(input.space, input.scope), value);
|
|
3354
3455
|
}
|
|
@@ -3382,8 +3483,8 @@ var startHydration = (registry, appId, storage, minted) => {
|
|
|
3382
3483
|
if (existing) return existing;
|
|
3383
3484
|
const slot = deviceIdStorageKey(appId);
|
|
3384
3485
|
const degraded = () => {
|
|
3385
|
-
var
|
|
3386
|
-
return { value: (
|
|
3486
|
+
var _a;
|
|
3487
|
+
return { value: (_a = registry.keys.get(appId)) != null ? _a : minted, durable: false };
|
|
3387
3488
|
};
|
|
3388
3489
|
const adopted = (value) => ({ value, durable: true });
|
|
3389
3490
|
let run;
|
|
@@ -3396,8 +3497,8 @@ var startHydration = (registry, appId, storage, minted) => {
|
|
|
3396
3497
|
}
|
|
3397
3498
|
return Promise.resolve(storage.setItem(slot, minted)).then(
|
|
3398
3499
|
() => {
|
|
3399
|
-
var
|
|
3400
|
-
return adopted((
|
|
3500
|
+
var _a;
|
|
3501
|
+
return adopted((_a = registry.keys.get(appId)) != null ? _a : minted);
|
|
3401
3502
|
},
|
|
3402
3503
|
degraded
|
|
3403
3504
|
);
|
|
@@ -3407,17 +3508,17 @@ var startHydration = (registry, appId, storage, minted) => {
|
|
|
3407
3508
|
}
|
|
3408
3509
|
registry.pending.set(appId, run);
|
|
3409
3510
|
void run.then((outcome) => {
|
|
3410
|
-
var
|
|
3511
|
+
var _a;
|
|
3411
3512
|
if (outcome.durable) return;
|
|
3412
|
-
(
|
|
3513
|
+
(_a = registry.pending) == null ? void 0 : _a.delete(appId);
|
|
3413
3514
|
registry.hydrating.delete(appId);
|
|
3414
3515
|
});
|
|
3415
3516
|
return run;
|
|
3416
3517
|
};
|
|
3417
3518
|
var resolveAutoDeviceKey = (opts = {}) => {
|
|
3418
|
-
var
|
|
3519
|
+
var _a, _b;
|
|
3419
3520
|
const registry = autoDeviceKeyRegistry();
|
|
3420
|
-
const appId = (
|
|
3521
|
+
const appId = (_a = opts.appId) != null ? _a : "default";
|
|
3421
3522
|
let id = registry.keys.get(appId);
|
|
3422
3523
|
if (!id) {
|
|
3423
3524
|
id = mintDeviceId();
|
|
@@ -3431,13 +3532,13 @@ var resolveAutoDeviceKey = (opts = {}) => {
|
|
|
3431
3532
|
return (_b = registry.keys.get(appId)) != null ? _b : id;
|
|
3432
3533
|
};
|
|
3433
3534
|
var hydrateAutoDeviceKey = async (opts = {}) => {
|
|
3434
|
-
var
|
|
3435
|
-
return (_b = (
|
|
3535
|
+
var _a, _b;
|
|
3536
|
+
return (_b = (_a = await hydrateDeviceIdentity(opts)) == null ? void 0 : _a.value) != null ? _b : resolveAutoDeviceKey(opts);
|
|
3436
3537
|
};
|
|
3437
3538
|
var hydrateDeviceIdentity = async (opts = {}) => {
|
|
3438
|
-
var
|
|
3539
|
+
var _a, _b, _c;
|
|
3439
3540
|
const id = resolveAutoDeviceKey(opts);
|
|
3440
|
-
const appId = (
|
|
3541
|
+
const appId = (_a = opts.appId) != null ? _a : "default";
|
|
3441
3542
|
const record = (value, durable) => resolveIdentity({ value, space: "device", source: "auto", durable, scope: appId });
|
|
3442
3543
|
if (!opts.storage) return record(id, false);
|
|
3443
3544
|
const registry = autoDeviceKeyRegistry();
|
|
@@ -3447,20 +3548,11 @@ var hydrateDeviceIdentity = async (opts = {}) => {
|
|
|
3447
3548
|
return record(outcome.value, outcome.durable);
|
|
3448
3549
|
};
|
|
3449
3550
|
var resetAutoDeviceKeys = () => {
|
|
3450
|
-
var
|
|
3551
|
+
var _a;
|
|
3451
3552
|
const registry = autoDeviceKeyRegistry();
|
|
3452
3553
|
registry.keys.clear();
|
|
3453
3554
|
registry.hydrating.clear();
|
|
3454
|
-
(
|
|
3455
|
-
};
|
|
3456
|
-
|
|
3457
|
-
// src/utils/warnInDev.ts
|
|
3458
|
-
var warnInDev = (message) => {
|
|
3459
|
-
if (typeof __DEV__ !== "undefined" && __DEV__ && typeof console !== "undefined" && console.warn) {
|
|
3460
|
-
console.warn(message);
|
|
3461
|
-
return true;
|
|
3462
|
-
}
|
|
3463
|
-
return false;
|
|
3555
|
+
(_a = registry.pending) == null ? void 0 : _a.clear();
|
|
3464
3556
|
};
|
|
3465
3557
|
|
|
3466
3558
|
// src/analytics/currentSession.ts
|
|
@@ -3562,9 +3654,9 @@ var sanitizeUserId = (raw) => {
|
|
|
3562
3654
|
};
|
|
3563
3655
|
var looksLikeEmail = (value) => typeof value === "string" && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
|
|
3564
3656
|
var identifyOnboarding = async (opts) => {
|
|
3565
|
-
var
|
|
3657
|
+
var _a, _b, _c;
|
|
3566
3658
|
const userId = sanitizeUserId(opts.userId);
|
|
3567
|
-
if (!userId || !((
|
|
3659
|
+
if (!userId || !((_a = opts.config) == null ? void 0 : _a.serverUrl)) return false;
|
|
3568
3660
|
let contextId = ((_b = opts.contextId) == null ? void 0 : _b.trim()) || void 0;
|
|
3569
3661
|
if (!contextId && opts.storage) {
|
|
3570
3662
|
const key = (_c = opts.persistKey) != null ? _c : opts.appId ? sessionStorageKey(opts.appId) : void 0;
|
|
@@ -3635,11 +3727,11 @@ var clearUserContext = async (opts = {}) => {
|
|
|
3635
3727
|
}
|
|
3636
3728
|
};
|
|
3637
3729
|
var activationJoinContext = (deviceKey) => {
|
|
3638
|
-
var
|
|
3639
|
-
return (
|
|
3730
|
+
var _a;
|
|
3731
|
+
return (_a = resolveUserContext({ deviceKey }).userContext) != null ? _a : {};
|
|
3640
3732
|
};
|
|
3641
3733
|
var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
3642
|
-
var
|
|
3734
|
+
var _a;
|
|
3643
3735
|
const result = {};
|
|
3644
3736
|
const bucket = {};
|
|
3645
3737
|
const userId = sanitizeUserId(ctx.userId);
|
|
@@ -3649,7 +3741,7 @@ var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
|
3649
3741
|
result.deviceKey = deviceKey;
|
|
3650
3742
|
bucket.device_key = deviceKey;
|
|
3651
3743
|
}
|
|
3652
|
-
const appVersion = (
|
|
3744
|
+
const appVersion = (_a = cleanString(ctx.appVersion)) != null ? _a : cleanString(opts.autoAppVersion);
|
|
3653
3745
|
if (appVersion) {
|
|
3654
3746
|
result.appVersion = appVersion;
|
|
3655
3747
|
bucket.app_version = appVersion;
|
|
@@ -3667,6 +3759,43 @@ var resolveUserContext = (ctx = {}, opts = {}) => {
|
|
|
3667
3759
|
if (Object.keys(bucket).length > 0) result.userContext = bucket;
|
|
3668
3760
|
return result;
|
|
3669
3761
|
};
|
|
3762
|
+
|
|
3763
|
+
// src/permissions/permissionMemory.ts
|
|
3764
|
+
var permissionStorageKey = (appId) => `wireai:permissions:${appId}`;
|
|
3765
|
+
var readSettledPermissions = (raw, sessionId) => {
|
|
3766
|
+
if (!raw || !sessionId) return [];
|
|
3767
|
+
try {
|
|
3768
|
+
const parsed = JSON.parse(raw);
|
|
3769
|
+
if (typeof parsed !== "object" || parsed === null) return [];
|
|
3770
|
+
const record = parsed;
|
|
3771
|
+
if (record.sessionId !== sessionId || !Array.isArray(record.ids)) return [];
|
|
3772
|
+
return record.ids.filter((id) => typeof id === "string" && id.length > 0);
|
|
3773
|
+
} catch {
|
|
3774
|
+
return [];
|
|
3775
|
+
}
|
|
3776
|
+
};
|
|
3777
|
+
var loadSettledPermissions = async (storage, key, sessionId) => {
|
|
3778
|
+
try {
|
|
3779
|
+
return readSettledPermissions(await withTimeout(storage.getItem(key), READ_TIMEOUT_MS), sessionId);
|
|
3780
|
+
} catch {
|
|
3781
|
+
return [];
|
|
3782
|
+
}
|
|
3783
|
+
};
|
|
3784
|
+
var saveSettledPermissions = (storage, key, sessionId, ids) => {
|
|
3785
|
+
try {
|
|
3786
|
+
const record = { sessionId, ids: [...ids] };
|
|
3787
|
+
void storage.setItem(key, JSON.stringify(record)).catch(() => {
|
|
3788
|
+
});
|
|
3789
|
+
} catch {
|
|
3790
|
+
}
|
|
3791
|
+
};
|
|
3792
|
+
var clearSettledPermissions = (storage, key) => {
|
|
3793
|
+
try {
|
|
3794
|
+
void storage.removeItem(key).catch(() => {
|
|
3795
|
+
});
|
|
3796
|
+
} catch {
|
|
3797
|
+
}
|
|
3798
|
+
};
|
|
3670
3799
|
var AUTO_JOIN_HYDRATION_TIMEOUT_MS = 1500;
|
|
3671
3800
|
var WireOnboarding = ({
|
|
3672
3801
|
config,
|
|
@@ -3691,20 +3820,21 @@ var WireOnboarding = ({
|
|
|
3691
3820
|
retainSessionOnComplete,
|
|
3692
3821
|
userContext,
|
|
3693
3822
|
userId,
|
|
3694
|
-
autoJoinKey = true
|
|
3823
|
+
autoJoinKey = true,
|
|
3824
|
+
permissionScreens
|
|
3695
3825
|
}) => {
|
|
3696
|
-
var
|
|
3697
|
-
const boundUserId =
|
|
3698
|
-
const device =
|
|
3826
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3827
|
+
const boundUserId = React19.useMemo(() => sanitizeUserId(userId), [userId]);
|
|
3828
|
+
const device = React19.useMemo(() => {
|
|
3699
3829
|
const collected = collectDeviceContext();
|
|
3700
3830
|
return config.appVersion ? { ...collected, appVersion: config.appVersion } : collected;
|
|
3701
3831
|
}, [config.appVersion]);
|
|
3702
3832
|
const userContextKey = userContext ? JSON.stringify(userContext) : "";
|
|
3703
|
-
const userContextStable =
|
|
3833
|
+
const userContextStable = React19.useMemo(
|
|
3704
3834
|
() => userContextKey ? JSON.parse(userContextKey) : void 0,
|
|
3705
3835
|
[userContextKey]
|
|
3706
3836
|
);
|
|
3707
|
-
const hostJoinIdentity =
|
|
3837
|
+
const hostJoinIdentity = React19.useMemo(
|
|
3708
3838
|
() => resolveIdentity({
|
|
3709
3839
|
value: userContextStable == null ? void 0 : userContextStable.device_key,
|
|
3710
3840
|
space: "device",
|
|
@@ -3716,8 +3846,8 @@ var WireOnboarding = ({
|
|
|
3716
3846
|
const missingJoinKey = !hostJoinIdentity;
|
|
3717
3847
|
const autoJoinPossible = Boolean(storage) && autoJoinKey !== false;
|
|
3718
3848
|
const wantsAutoJoin = missingJoinKey && autoJoinPossible;
|
|
3719
|
-
const [autoJoinOutcome, setAutoJoinOutcome] =
|
|
3720
|
-
|
|
3849
|
+
const [autoJoinOutcome, setAutoJoinOutcome] = React19.useState(void 0);
|
|
3850
|
+
React19.useEffect(() => {
|
|
3721
3851
|
if (!wantsAutoJoin || autoJoinOutcome !== void 0 || !storage) return;
|
|
3722
3852
|
let cancelled = false;
|
|
3723
3853
|
const timer = setTimeout(() => {
|
|
@@ -3735,24 +3865,24 @@ var WireOnboarding = ({
|
|
|
3735
3865
|
clearTimeout(timer);
|
|
3736
3866
|
};
|
|
3737
3867
|
}, [wantsAutoJoin, autoJoinOutcome, config.appId, storage]);
|
|
3738
|
-
const injectedJoinKey = wantsAutoJoin ? (
|
|
3868
|
+
const injectedJoinKey = wantsAutoJoin ? (_a = autoJoinOutcome == null ? void 0 : autoJoinOutcome.key) != null ? _a : void 0 : void 0;
|
|
3739
3869
|
const autoJoinPending = wantsAutoJoin && autoJoinOutcome === void 0;
|
|
3740
|
-
const effectiveUserContext =
|
|
3870
|
+
const effectiveUserContext = React19.useMemo(
|
|
3741
3871
|
() => injectedJoinKey ? { ...userContextStable, ...activationJoinContext(injectedJoinKey) } : userContextStable,
|
|
3742
3872
|
[userContextStable, injectedJoinKey]
|
|
3743
3873
|
);
|
|
3744
|
-
const frozenWireContextRef =
|
|
3874
|
+
const frozenWireContextRef = React19.useRef(null);
|
|
3745
3875
|
if (!autoJoinPending && frozenWireContextRef.current === null) {
|
|
3746
3876
|
frozenWireContextRef.current = effectiveUserContext ? JSON.stringify(effectiveUserContext) : "";
|
|
3747
3877
|
}
|
|
3748
3878
|
const startupUserContextKey = (_b = frozenWireContextRef.current) != null ? _b : "";
|
|
3749
|
-
const startupUserContext =
|
|
3879
|
+
const startupUserContext = React19.useMemo(
|
|
3750
3880
|
() => startupUserContextKey ? JSON.parse(startupUserContextKey) : void 0,
|
|
3751
3881
|
[startupUserContextKey]
|
|
3752
3882
|
);
|
|
3753
3883
|
const warnMissingJoinKey = missingJoinKey && !injectedJoinKey && !autoJoinPending;
|
|
3754
3884
|
const autoJoinReason = autoJoinKey === false ? "you passed autoJoinKey={false}." : !storage ? "it got no `storage` prop, and without persistence its key would be different on every launch, which corrupts min_sessions instead of merely leaving the join empty." : (autoJoinOutcome == null ? void 0 : autoJoinOutcome.key) === null && autoJoinOutcome.reason === "not-durable" ? "your `storage` adapter answered but could not persist the key (the read or the write failed), so the key would be different on every launch, which corrupts min_sessions instead of merely leaving the join empty. Check the adapter you passed as `storage`." : "your `storage` adapter did not answer in time.";
|
|
3755
|
-
|
|
3885
|
+
React19.useEffect(() => {
|
|
3756
3886
|
if (!warnMissingJoinKey) return;
|
|
3757
3887
|
warnInDev(
|
|
3758
3888
|
"[wireai] <WireOnboarding> got no user_context.device_key, so this onboarding session can never be joined to the app's later events and the `activated` funnel will read zero. Pass userContext={activationJoinContext(deviceKey)} \u2014 and if your app owns no device id, userContext={activationJoinContext(resolveAutoDeviceKey({ appId, storage }))} returns the SAME id the analytics side stamps. Never hand-write userContext={{ deviceKey }}. The kit did NOT auto-inject its own key here because " + autoJoinReason
|
|
@@ -3760,28 +3890,29 @@ var WireOnboarding = ({
|
|
|
3760
3890
|
}, [warnMissingJoinKey, autoJoinReason]);
|
|
3761
3891
|
const hostKeyElsewhere = missingJoinKey ? hostIdentity("device", config.appId) : void 0;
|
|
3762
3892
|
const warnHostKeyElsewhere = Boolean(hostKeyElsewhere) && Boolean(injectedJoinKey);
|
|
3763
|
-
|
|
3893
|
+
React19.useEffect(() => {
|
|
3764
3894
|
if (!warnHostKeyElsewhere) return;
|
|
3765
3895
|
warnInDev(
|
|
3766
3896
|
`[wireai] <WireOnboarding> got no user_context.device_key, so the kit injected its own \u2014 but another surface in this app was constructed WITH a host-supplied device key ("${hostKeyElsewhere}"). Your app events carry that id and this onboarding session carries the kit's, so the two land in disjoint id spaces and the \`activated\` funnel still reads zero. Pass the SAME id here: userContext={activationJoinContext(deviceKey)}.`
|
|
3767
3897
|
);
|
|
3768
3898
|
}, [warnHostKeyElsewhere, hostKeyElsewhere]);
|
|
3769
3899
|
const misspelledJoinKey = missingJoinKey && typeof (userContextStable == null ? void 0 : userContextStable.deviceKey) === "string" && Boolean(userContextStable.deviceKey.trim());
|
|
3770
|
-
|
|
3900
|
+
React19.useEffect(() => {
|
|
3771
3901
|
if (!misspelledJoinKey || !injectedJoinKey) return;
|
|
3772
3902
|
warnInDev(
|
|
3773
3903
|
"[wireai] <WireOnboarding> got userContext={{ deviceKey }}, which is NOT the wire key \u2014 the server's device lookup reads `device_key`. The kit auto-injected its own device_key so this session is at least self-consistent, but your app's own events carry YOUR id, so the two still will not join and the `activated` funnel stays zero. Pass userContext={activationJoinContext(deviceKey)} instead."
|
|
3774
3904
|
);
|
|
3775
3905
|
}, [misspelledJoinKey, injectedJoinKey]);
|
|
3776
|
-
const clientContext =
|
|
3906
|
+
const clientContext = React19.useMemo(
|
|
3777
3907
|
() => ({ device, userContext: effectiveUserContext, userId: boundUserId }),
|
|
3778
3908
|
[device, effectiveUserContext, boundUserId]
|
|
3779
3909
|
);
|
|
3780
|
-
const [session, setSession] =
|
|
3910
|
+
const [session, setSession] = React19.useState(
|
|
3781
3911
|
() => storage ? null : { id: makeSessionId(), resumed: false }
|
|
3782
3912
|
);
|
|
3783
3913
|
const storageKey = persistKey != null ? persistKey : sessionStorageKey(config.appId);
|
|
3784
|
-
|
|
3914
|
+
const permissionsKey = permissionStorageKey(config.appId);
|
|
3915
|
+
React19.useEffect(() => {
|
|
3785
3916
|
if (!storage || session) return;
|
|
3786
3917
|
let cancelled = false;
|
|
3787
3918
|
void loadPersistedSession(storage, storageKey, sessionTtlMs).then((loaded) => {
|
|
@@ -3791,20 +3922,51 @@ var WireOnboarding = ({
|
|
|
3791
3922
|
cancelled = true;
|
|
3792
3923
|
};
|
|
3793
3924
|
}, [storage, storageKey, sessionTtlMs, session]);
|
|
3794
|
-
const handleComplete =
|
|
3925
|
+
const handleComplete = React19.useCallback(
|
|
3795
3926
|
(result) => {
|
|
3796
|
-
if (storage && shouldClearOnComplete(retainSessionOnComplete))
|
|
3927
|
+
if (storage && shouldClearOnComplete(retainSessionOnComplete)) {
|
|
3928
|
+
clearPersistedSession(storage, storageKey);
|
|
3929
|
+
clearSettledPermissions(storage, permissionsKey);
|
|
3930
|
+
}
|
|
3797
3931
|
onComplete(result);
|
|
3798
3932
|
},
|
|
3799
|
-
[storage, storageKey, retainSessionOnComplete, onComplete]
|
|
3933
|
+
[storage, storageKey, permissionsKey, retainSessionOnComplete, onComplete]
|
|
3800
3934
|
);
|
|
3801
3935
|
const sessionId = (_c = session == null ? void 0 : session.id) != null ? _c : "";
|
|
3802
|
-
const
|
|
3936
|
+
const wantsPermissionMemory = Boolean(storage) && ((_d = permissionScreens == null ? void 0 : permissionScreens.length) != null ? _d : 0) > 0;
|
|
3937
|
+
const [settledPermissions, setSettledPermissions] = React19.useState(void 0);
|
|
3938
|
+
React19.useEffect(() => {
|
|
3939
|
+
if (!wantsPermissionMemory || !storage || !sessionId || settledPermissions !== void 0) return;
|
|
3940
|
+
let cancelled = false;
|
|
3941
|
+
void loadSettledPermissions(storage, permissionsKey, sessionId).then((ids) => {
|
|
3942
|
+
if (!cancelled) setSettledPermissions(ids);
|
|
3943
|
+
});
|
|
3944
|
+
return () => {
|
|
3945
|
+
cancelled = true;
|
|
3946
|
+
};
|
|
3947
|
+
}, [wantsPermissionMemory, storage, permissionsKey, sessionId, settledPermissions]);
|
|
3948
|
+
const settledPermissionsRef = React19.useRef(void 0);
|
|
3949
|
+
settledPermissionsRef.current = settledPermissions;
|
|
3950
|
+
const handlePermissionSettled = React19.useCallback(
|
|
3951
|
+
(id) => {
|
|
3952
|
+
var _a2;
|
|
3953
|
+
const current = (_a2 = settledPermissionsRef.current) != null ? _a2 : [];
|
|
3954
|
+
if (current.includes(id)) return;
|
|
3955
|
+
const next = [...current, id];
|
|
3956
|
+
settledPermissionsRef.current = next;
|
|
3957
|
+
setSettledPermissions(next);
|
|
3958
|
+
if (storage && wantsPermissionMemory && sessionId) {
|
|
3959
|
+
saveSettledPermissions(storage, permissionsKey, sessionId, next);
|
|
3960
|
+
}
|
|
3961
|
+
},
|
|
3962
|
+
[storage, wantsPermissionMemory, permissionsKey, sessionId]
|
|
3963
|
+
);
|
|
3964
|
+
const startupUserIdRef = React19.useRef(boundUserId);
|
|
3803
3965
|
const metadataKey = config.metadata ? JSON.stringify(config.metadata) : "";
|
|
3804
|
-
const metadataStable =
|
|
3966
|
+
const metadataStable = React19.useMemo(() => metadataKey ? JSON.parse(metadataKey) : void 0, [metadataKey]);
|
|
3805
3967
|
const componentNamesKey = (components != null ? components : onboardingComponents).map((c) => c.name).join(",");
|
|
3806
|
-
const componentsStable =
|
|
3807
|
-
const llm =
|
|
3968
|
+
const componentsStable = React19.useMemo(() => components != null ? components : onboardingComponents, [componentNamesKey]);
|
|
3969
|
+
const llm = React19.useMemo(() => {
|
|
3808
3970
|
const baseUrl = config.serverUrl.replace(/\/$/, "");
|
|
3809
3971
|
return {
|
|
3810
3972
|
provider: "a2a",
|
|
@@ -3834,13 +3996,13 @@ var WireOnboarding = ({
|
|
|
3834
3996
|
timeoutMs: 6e4
|
|
3835
3997
|
};
|
|
3836
3998
|
}, [config.serverUrl, config.appId, config.apiKey, metadataStable, sessionId, componentsStable, device, startupUserContext]);
|
|
3837
|
-
const reportTarget =
|
|
3999
|
+
const reportTarget = React19.useMemo(
|
|
3838
4000
|
() => ({ serverUrl: config.serverUrl, apiKey: config.apiKey }),
|
|
3839
4001
|
[config.serverUrl, config.apiKey]
|
|
3840
4002
|
);
|
|
3841
|
-
const identifiedRef =
|
|
3842
|
-
const identifySeededRef =
|
|
3843
|
-
|
|
4003
|
+
const identifiedRef = React19.useRef(void 0);
|
|
4004
|
+
const identifySeededRef = React19.useRef(false);
|
|
4005
|
+
React19.useEffect(() => {
|
|
3844
4006
|
if (!session || !sessionId) return;
|
|
3845
4007
|
if (!identifySeededRef.current) {
|
|
3846
4008
|
identifySeededRef.current = true;
|
|
@@ -3859,8 +4021,8 @@ var WireOnboarding = ({
|
|
|
3859
4021
|
return /* @__PURE__ */ jsxRuntime.jsx(OnboardingThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3860
4022
|
LoadingScreen,
|
|
3861
4023
|
{
|
|
3862
|
-
title: (
|
|
3863
|
-
hint: (
|
|
4024
|
+
title: (_e = copy == null ? void 0 : copy.restoringTitle) != null ? _e : DEFAULT_COPY.restoringTitle,
|
|
4025
|
+
hint: (_f = copy == null ? void 0 : copy.restoringHint) != null ? _f : DEFAULT_COPY.restoringHint
|
|
3864
4026
|
}
|
|
3865
4027
|
) });
|
|
3866
4028
|
}
|
|
@@ -3881,7 +4043,11 @@ var WireOnboarding = ({
|
|
|
3881
4043
|
reportTarget,
|
|
3882
4044
|
sessionId,
|
|
3883
4045
|
resumed: session.resumed,
|
|
3884
|
-
clientContext
|
|
4046
|
+
clientContext,
|
|
4047
|
+
permissionScreens,
|
|
4048
|
+
settledPermissions,
|
|
4049
|
+
permissionsPending: wantsPermissionMemory && settledPermissions === void 0,
|
|
4050
|
+
onPermissionSettled: handlePermissionSettled
|
|
3885
4051
|
}
|
|
3886
4052
|
) }) }) }) });
|
|
3887
4053
|
};
|
|
@@ -3895,16 +4061,16 @@ function DemoOnboarding({
|
|
|
3895
4061
|
onComplete,
|
|
3896
4062
|
renderTrigger
|
|
3897
4063
|
}) {
|
|
3898
|
-
const [open, setOpen] =
|
|
3899
|
-
const [runId, setRunId] =
|
|
3900
|
-
const t =
|
|
3901
|
-
const
|
|
3902
|
-
const openDemo =
|
|
4064
|
+
const [open, setOpen] = React19.useState(false);
|
|
4065
|
+
const [runId, setRunId] = React19.useState(0);
|
|
4066
|
+
const t = React19.useMemo(() => mergeTheme(theme != null ? theme : {}), [theme]);
|
|
4067
|
+
const styles18 = React19.useMemo(() => makeStyles5(t), [t]);
|
|
4068
|
+
const openDemo = React19.useCallback(() => {
|
|
3903
4069
|
setRunId((n) => n + 1);
|
|
3904
4070
|
setOpen(true);
|
|
3905
4071
|
}, []);
|
|
3906
|
-
const close =
|
|
3907
|
-
const finish =
|
|
4072
|
+
const close = React19.useCallback(() => setOpen(false), []);
|
|
4073
|
+
const finish = React19.useCallback(
|
|
3908
4074
|
(result) => {
|
|
3909
4075
|
onComplete == null ? void 0 : onComplete(result);
|
|
3910
4076
|
setOpen(false);
|
|
@@ -3912,7 +4078,7 @@ function DemoOnboarding({
|
|
|
3912
4078
|
[onComplete]
|
|
3913
4079
|
);
|
|
3914
4080
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3915
|
-
renderTrigger ? renderTrigger(openDemo) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: openDemo, style:
|
|
4081
|
+
renderTrigger ? renderTrigger(openDemo) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: openDemo, style: styles18.trigger, accessibilityRole: "button", children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles18.triggerText, children: label }) }),
|
|
3916
4082
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3917
4083
|
reactNative.Modal,
|
|
3918
4084
|
{
|
|
@@ -3920,7 +4086,7 @@ function DemoOnboarding({
|
|
|
3920
4086
|
animationType: "slide",
|
|
3921
4087
|
presentationStyle: "fullScreen",
|
|
3922
4088
|
onRequestClose: close,
|
|
3923
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style:
|
|
4089
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles18.modal, children: config ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3924
4090
|
WireOnboarding,
|
|
3925
4091
|
{
|
|
3926
4092
|
config,
|
|
@@ -3933,10 +4099,10 @@ function DemoOnboarding({
|
|
|
3933
4099
|
onError: close
|
|
3934
4100
|
},
|
|
3935
4101
|
runId
|
|
3936
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style:
|
|
3937
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style:
|
|
3938
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style:
|
|
3939
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: close, style:
|
|
4102
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles18.notice, children: [
|
|
4103
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles18.noticeTitle, children: "Wire AI not configured" }),
|
|
4104
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles18.noticeBody, children: "Set the Wire AI key + server URL (e.g. via wireConfigFromEnv) to demo the AI onboarding here." }),
|
|
4105
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: close, style: styles18.trigger, accessibilityRole: "button", children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles18.triggerText, children: "Close" }) })
|
|
3940
4106
|
] }) })
|
|
3941
4107
|
}
|
|
3942
4108
|
)
|
|
@@ -4022,13 +4188,13 @@ var CENTERED_MODAL_ANIM = {
|
|
|
4022
4188
|
/** Peak dim of the backdrop at progress 1. */
|
|
4023
4189
|
backdropOpacity: 0.55
|
|
4024
4190
|
};
|
|
4025
|
-
var _CenteredModal =
|
|
4191
|
+
var _CenteredModal = React19.forwardRef(
|
|
4026
4192
|
({ theme, dismissible = true, onDismiss, children }, ref) => {
|
|
4027
|
-
const progress =
|
|
4028
|
-
const [open, setOpen] =
|
|
4029
|
-
const closingRef =
|
|
4193
|
+
const progress = React19.useRef(new reactNative.Animated.Value(0)).current;
|
|
4194
|
+
const [open, setOpen] = React19.useState(true);
|
|
4195
|
+
const closingRef = React19.useRef(false);
|
|
4030
4196
|
const reduced = useReducedMotion();
|
|
4031
|
-
|
|
4197
|
+
React19.useEffect(() => {
|
|
4032
4198
|
const anim = reduced ? reactNative.Animated.timing(progress, {
|
|
4033
4199
|
toValue: 1,
|
|
4034
4200
|
duration: REDUCED_FADE_MS,
|
|
@@ -4042,7 +4208,7 @@ var _CenteredModal = React18.forwardRef(
|
|
|
4042
4208
|
anim.start();
|
|
4043
4209
|
return () => anim.stop();
|
|
4044
4210
|
}, [progress, reduced]);
|
|
4045
|
-
const close =
|
|
4211
|
+
const close = React19.useCallback(() => {
|
|
4046
4212
|
if (closingRef.current) return;
|
|
4047
4213
|
closingRef.current = true;
|
|
4048
4214
|
reactNative.Animated.timing(progress, {
|
|
@@ -4055,15 +4221,15 @@ var _CenteredModal = React18.forwardRef(
|
|
|
4055
4221
|
onDismiss();
|
|
4056
4222
|
});
|
|
4057
4223
|
}, [progress, onDismiss, reduced]);
|
|
4058
|
-
|
|
4059
|
-
|
|
4224
|
+
React19.useImperativeHandle(ref, () => ({ close }), [close]);
|
|
4225
|
+
React19.useEffect(() => {
|
|
4060
4226
|
const sub = reactNative.BackHandler.addEventListener("hardwareBackPress", () => {
|
|
4061
4227
|
if (dismissible) close();
|
|
4062
4228
|
return true;
|
|
4063
4229
|
});
|
|
4064
4230
|
return () => sub.remove();
|
|
4065
4231
|
}, [dismissible, close]);
|
|
4066
|
-
const onBackdrop =
|
|
4232
|
+
const onBackdrop = React19.useCallback(() => {
|
|
4067
4233
|
if (dismissible) close();
|
|
4068
4234
|
}, [dismissible, close]);
|
|
4069
4235
|
const backdropOpacity = progress.interpolate({
|
|
@@ -4086,25 +4252,25 @@ var _CenteredModal = React18.forwardRef(
|
|
|
4086
4252
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4087
4253
|
reactNative.Animated.View,
|
|
4088
4254
|
{
|
|
4089
|
-
style: [
|
|
4255
|
+
style: [styles17.backdrop, { opacity: backdropOpacity }],
|
|
4090
4256
|
pointerEvents: "none"
|
|
4091
4257
|
}
|
|
4092
4258
|
),
|
|
4093
4259
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4094
4260
|
reactNative.Pressable,
|
|
4095
4261
|
{
|
|
4096
|
-
style:
|
|
4262
|
+
style: styles17.fill,
|
|
4097
4263
|
onPress: onBackdrop,
|
|
4098
4264
|
accessibilityRole: "button",
|
|
4099
4265
|
accessibilityLabel: "Dismiss",
|
|
4100
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(reactNativeSafeAreaContext.SafeAreaView, { style:
|
|
4101
|
-
}, style:
|
|
4266
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(reactNativeSafeAreaContext.SafeAreaView, { style: styles17.center, pointerEvents: "box-none", children: /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: () => {
|
|
4267
|
+
}, style: styles17.cardWrap, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4102
4268
|
reactNative.Animated.View,
|
|
4103
4269
|
{
|
|
4104
4270
|
accessibilityViewIsModal: true,
|
|
4105
4271
|
accessibilityRole: "alert",
|
|
4106
4272
|
style: [
|
|
4107
|
-
|
|
4273
|
+
styles17.card,
|
|
4108
4274
|
{
|
|
4109
4275
|
backgroundColor: theme.colors.surface,
|
|
4110
4276
|
borderRadius: theme.radius.lg,
|
|
@@ -4125,8 +4291,8 @@ var _CenteredModal = React18.forwardRef(
|
|
|
4125
4291
|
}
|
|
4126
4292
|
);
|
|
4127
4293
|
_CenteredModal.displayName = "CenteredModal";
|
|
4128
|
-
var CenteredModal =
|
|
4129
|
-
var
|
|
4294
|
+
var CenteredModal = React19__default.default.memo(_CenteredModal);
|
|
4295
|
+
var styles17 = reactNative.StyleSheet.create({
|
|
4130
4296
|
fill: { flex: 1 },
|
|
4131
4297
|
backdrop: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, backgroundColor: "#000" },
|
|
4132
4298
|
center: { flex: 1, alignItems: "center", justifyContent: "center", padding: 24 },
|
|
@@ -4159,10 +4325,10 @@ var readEnabled = (raw) => {
|
|
|
4159
4325
|
return { enabled: true };
|
|
4160
4326
|
};
|
|
4161
4327
|
var parseWireFeatures = (raw) => {
|
|
4162
|
-
var
|
|
4328
|
+
var _a;
|
|
4163
4329
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return defaultWireFeatures;
|
|
4164
4330
|
const src = raw;
|
|
4165
|
-
const modeRaw = (
|
|
4331
|
+
const modeRaw = (_a = src.onboarding) == null ? void 0 : _a.mode;
|
|
4166
4332
|
const mode = typeof modeRaw === "string" && VALID_MODES.includes(modeRaw) ? modeRaw : "ai";
|
|
4167
4333
|
return {
|
|
4168
4334
|
coachmarks: readEnabled(src.coachmarks),
|
|
@@ -4219,10 +4385,10 @@ var writeCachedFeatures = (storage, key, features) => {
|
|
|
4219
4385
|
// src/features/fetchWireFeatures.ts
|
|
4220
4386
|
var DEFAULT_TIMEOUT_MS = 4e3;
|
|
4221
4387
|
var failOpen = async (storage, key) => {
|
|
4222
|
-
var
|
|
4388
|
+
var _a;
|
|
4223
4389
|
if (!storage) return defaultWireFeatures;
|
|
4224
4390
|
const cached2 = await readCachedFeatures(storage, key);
|
|
4225
|
-
return (
|
|
4391
|
+
return (_a = cached2 == null ? void 0 : cached2.features) != null ? _a : defaultWireFeatures;
|
|
4226
4392
|
};
|
|
4227
4393
|
var fetchWithTimeout = async (url, apiKey, timeoutMs) => {
|
|
4228
4394
|
const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
|
|
@@ -4255,16 +4421,16 @@ var fetchWireFeatures = async (config) => {
|
|
|
4255
4421
|
}
|
|
4256
4422
|
};
|
|
4257
4423
|
var useStableValue = (value, isEqual) => {
|
|
4258
|
-
const ref =
|
|
4424
|
+
const ref = React19.useRef(value);
|
|
4259
4425
|
if (!isEqual(ref.current, value)) ref.current = value;
|
|
4260
4426
|
return ref.current;
|
|
4261
4427
|
};
|
|
4262
4428
|
var sameFetchKey = (a, b) => (a == null ? void 0 : a.serverUrl) === (b == null ? void 0 : b.serverUrl) && (a == null ? void 0 : a.apiKey) === (b == null ? void 0 : b.apiKey) && (a == null ? void 0 : a.appId) === (b == null ? void 0 : b.appId);
|
|
4263
4429
|
var useWireFeatures = (config) => {
|
|
4264
4430
|
const stableConfig = useStableValue(config, sameFetchKey);
|
|
4265
|
-
const [flags, setFlags] =
|
|
4431
|
+
const [flags, setFlags] = React19.useState(defaultWireFeatures);
|
|
4266
4432
|
const canFetch = !!(stableConfig == null ? void 0 : stableConfig.serverUrl) && !!(stableConfig == null ? void 0 : stableConfig.apiKey);
|
|
4267
|
-
|
|
4433
|
+
React19.useEffect(() => {
|
|
4268
4434
|
if (!canFetch) {
|
|
4269
4435
|
setFlags((prev) => featuresEqual(prev, defaultWireFeatures) ? prev : defaultWireFeatures);
|
|
4270
4436
|
return;
|
|
@@ -4281,9 +4447,9 @@ var useWireFeatures = (config) => {
|
|
|
4281
4447
|
return flags;
|
|
4282
4448
|
};
|
|
4283
4449
|
var CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("wireai.features.context");
|
|
4284
|
-
var globalObj =
|
|
4450
|
+
var globalObj = globalThis;
|
|
4285
4451
|
if (!globalObj[CONTEXT_SYMBOL]) {
|
|
4286
|
-
globalObj[CONTEXT_SYMBOL] =
|
|
4452
|
+
globalObj[CONTEXT_SYMBOL] = React19.createContext(null);
|
|
4287
4453
|
}
|
|
4288
4454
|
var WireFeaturesContext = globalObj[CONTEXT_SYMBOL];
|
|
4289
4455
|
var WireFeaturesProvider = ({
|
|
@@ -4293,17 +4459,17 @@ var WireFeaturesProvider = ({
|
|
|
4293
4459
|
}) => {
|
|
4294
4460
|
const fetched = useWireFeatures(flags ? void 0 : config);
|
|
4295
4461
|
const value = flags != null ? flags : fetched;
|
|
4296
|
-
const stable =
|
|
4462
|
+
const stable = React19.useMemo(() => value, [value]);
|
|
4297
4463
|
return /* @__PURE__ */ jsxRuntime.jsx(WireFeaturesContext.Provider, { value: stable, children });
|
|
4298
4464
|
};
|
|
4299
4465
|
WireFeaturesProvider.displayName = "WireFeaturesProvider";
|
|
4300
|
-
var useWireFeaturesContext = () =>
|
|
4466
|
+
var useWireFeaturesContext = () => React19.useContext(WireFeaturesContext);
|
|
4301
4467
|
var useResolvedFeatures = (options) => {
|
|
4302
|
-
var
|
|
4468
|
+
var _a, _b, _c;
|
|
4303
4469
|
const ctx = useWireFeaturesContext();
|
|
4304
4470
|
const shouldFetch = !(options == null ? void 0 : options.flags) && ctx == null;
|
|
4305
4471
|
const fetched = useWireFeatures(shouldFetch ? options == null ? void 0 : options.config : void 0);
|
|
4306
|
-
return (_c = (_b = (
|
|
4472
|
+
return (_c = (_b = (_a = options == null ? void 0 : options.flags) != null ? _a : ctx) != null ? _b : fetched) != null ? _c : defaultWireFeatures;
|
|
4307
4473
|
};
|
|
4308
4474
|
|
|
4309
4475
|
// src/config/wireConfigFromEnv.ts
|
|
@@ -4313,8 +4479,8 @@ var WIRE_ENV_VARS = [
|
|
|
4313
4479
|
"EXPO_PUBLIC_WIREAI_APP_ID"
|
|
4314
4480
|
];
|
|
4315
4481
|
var wireConfigFromEnv = (overrides) => {
|
|
4316
|
-
var
|
|
4317
|
-
const apiKey = (
|
|
4482
|
+
var _a, _b, _c, _d, _e;
|
|
4483
|
+
const apiKey = (_a = overrides == null ? void 0 : overrides.apiKey) != null ? _a : process.env.EXPO_PUBLIC_WIREAI_API_KEY;
|
|
4318
4484
|
const serverUrl = (_b = overrides == null ? void 0 : overrides.serverUrl) != null ? _b : process.env.EXPO_PUBLIC_WIREAI_SERVER_URL;
|
|
4319
4485
|
const appId = (_d = (_c = overrides == null ? void 0 : overrides.appId) != null ? _c : process.env.EXPO_PUBLIC_WIREAI_APP_ID) != null ? _d : "default";
|
|
4320
4486
|
if (!apiKey || !serverUrl) {
|
|
@@ -4339,10 +4505,10 @@ var wireConfigFromEnv = (overrides) => {
|
|
|
4339
4505
|
|
|
4340
4506
|
// src/config/onboardingFlag.ts
|
|
4341
4507
|
var isOnboardingEnabled = (opts) => {
|
|
4342
|
-
var
|
|
4508
|
+
var _a;
|
|
4343
4509
|
const transportPresent = wireConfigFromEnv(opts == null ? void 0 : opts.config) !== null;
|
|
4344
4510
|
if (!transportPresent) return false;
|
|
4345
|
-
return (
|
|
4511
|
+
return (_a = opts == null ? void 0 : opts.remote) != null ? _a : true;
|
|
4346
4512
|
};
|
|
4347
4513
|
|
|
4348
4514
|
// src/analytics/analyticsEvent.ts
|
|
@@ -4377,6 +4543,11 @@ var toAnalyticsEvent = (event) => {
|
|
|
4377
4543
|
};
|
|
4378
4544
|
case "fallback":
|
|
4379
4545
|
return { name: WIRE_ONBOARDING_EVENTS.fallback, params: { reason: event.reason } };
|
|
4546
|
+
case "permission":
|
|
4547
|
+
return {
|
|
4548
|
+
name: permissionEventName(event.stage),
|
|
4549
|
+
params: permissionEventProps(event.permission, event.status)
|
|
4550
|
+
};
|
|
4380
4551
|
default: {
|
|
4381
4552
|
const _exhaustive = event;
|
|
4382
4553
|
return _exhaustive;
|
|
@@ -4432,9 +4603,9 @@ var resetActivationRevalidation = () => {
|
|
|
4432
4603
|
// src/activation/wireActivation.ts
|
|
4433
4604
|
var clean = cleanString;
|
|
4434
4605
|
var createWireActivation = (config) => {
|
|
4435
|
-
var
|
|
4606
|
+
var _a, _b;
|
|
4436
4607
|
const target = { serverUrl: config.serverUrl, apiKey: config.apiKey };
|
|
4437
|
-
const explicitDeviceKey = (_b = clean(config.deviceKey)) != null ? _b : clean((
|
|
4608
|
+
const explicitDeviceKey = (_b = clean(config.deviceKey)) != null ? _b : clean((_a = config.userContext) == null ? void 0 : _a.deviceKey);
|
|
4438
4609
|
resolveIdentity({
|
|
4439
4610
|
value: explicitDeviceKey,
|
|
4440
4611
|
space: "device",
|
|
@@ -4449,11 +4620,11 @@ var createWireActivation = (config) => {
|
|
|
4449
4620
|
if (!explicitDeviceKey) resolveAutoDeviceKey(autoDeviceKeyOptions);
|
|
4450
4621
|
const detectedAppVersion = detectAppVersion();
|
|
4451
4622
|
const applyContext = (event) => {
|
|
4452
|
-
var
|
|
4623
|
+
var _a2, _b2, _c;
|
|
4453
4624
|
const resolved = resolveUserContext(
|
|
4454
4625
|
// `??` is lazy on purpose: an explicit key must never even touch the auto registry.
|
|
4455
4626
|
{
|
|
4456
|
-
...(
|
|
4627
|
+
...(_a2 = config.userContext) != null ? _a2 : {},
|
|
4457
4628
|
deviceKey: explicitDeviceKey != null ? explicitDeviceKey : resolveAutoDeviceKey(autoDeviceKeyOptions)
|
|
4458
4629
|
},
|
|
4459
4630
|
{ autoAppVersion: (_b2 = config.appVersion) != null ? _b2 : detectedAppVersion }
|
|
@@ -4463,13 +4634,13 @@ var createWireActivation = (config) => {
|
|
|
4463
4634
|
}
|
|
4464
4635
|
if (resolved.userId && !event.user_id) event.user_id = resolved.userId;
|
|
4465
4636
|
};
|
|
4466
|
-
const track = async (
|
|
4467
|
-
if (!clean(
|
|
4637
|
+
const track = async (name, meta) => {
|
|
4638
|
+
if (!clean(name)) return false;
|
|
4468
4639
|
const sessionId = ensureCurrentSessionId();
|
|
4469
4640
|
const event = {
|
|
4470
4641
|
event_type: "app_event",
|
|
4471
4642
|
session_id: sessionId,
|
|
4472
|
-
question_key:
|
|
4643
|
+
question_key: name
|
|
4473
4644
|
};
|
|
4474
4645
|
if (meta && Object.keys(meta).length > 0) event.meta = JSON.stringify(meta);
|
|
4475
4646
|
applyContext(event);
|
|
@@ -4486,21 +4657,21 @@ var createWireActivation = (config) => {
|
|
|
4486
4657
|
getRevalidationVersion: getActivationRevalidationVersion
|
|
4487
4658
|
};
|
|
4488
4659
|
};
|
|
4489
|
-
var useActivationRevalidation = () =>
|
|
4660
|
+
var useActivationRevalidation = () => React19.useSyncExternalStore(
|
|
4490
4661
|
subscribeActivationRevalidation,
|
|
4491
4662
|
getActivationRevalidationVersion,
|
|
4492
4663
|
getActivationRevalidationVersion
|
|
4493
4664
|
);
|
|
4494
4665
|
var useWireActivation = (config) => {
|
|
4495
|
-
var
|
|
4496
|
-
const ref =
|
|
4497
|
-
const prevKeys =
|
|
4666
|
+
var _a;
|
|
4667
|
+
const ref = React19.useRef(void 0);
|
|
4668
|
+
const prevKeys = React19.useRef("");
|
|
4498
4669
|
const currentKeys = [
|
|
4499
4670
|
config.serverUrl,
|
|
4500
4671
|
config.apiKey,
|
|
4501
4672
|
config.appId,
|
|
4502
4673
|
config.deviceKey,
|
|
4503
|
-
(
|
|
4674
|
+
(_a = config.userContext) == null ? void 0 : _a.deviceKey
|
|
4504
4675
|
].join("|");
|
|
4505
4676
|
if (!ref.current || prevKeys.current !== currentKeys) {
|
|
4506
4677
|
prevKeys.current = currentKeys;
|
|
@@ -4526,8 +4697,8 @@ var WIRE_PURCHASE_EVENTS = {
|
|
|
4526
4697
|
var PLAN_TIER_CONTEXT_KEY = "plan_tier";
|
|
4527
4698
|
var asRecord = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
4528
4699
|
var activeEntitlement = (info, entitlementId) => {
|
|
4529
|
-
var
|
|
4530
|
-
const active = asRecord((_b = asRecord((
|
|
4700
|
+
var _a, _b;
|
|
4701
|
+
const active = asRecord((_b = asRecord((_a = asRecord(info)) == null ? void 0 : _a.entitlements)) == null ? void 0 : _b.active);
|
|
4531
4702
|
const found = active == null ? void 0 : active[entitlementId];
|
|
4532
4703
|
const entitlement = asRecord(found);
|
|
4533
4704
|
if (!entitlement) return void 0;
|
|
@@ -4600,19 +4771,19 @@ var createRevenueCatBridge = (config) => {
|
|
|
4600
4771
|
}
|
|
4601
4772
|
};
|
|
4602
4773
|
const syncPlanTier = (customerInfo) => {
|
|
4603
|
-
var
|
|
4774
|
+
var _a;
|
|
4604
4775
|
const tier = resolvePlanTier(customerInfo, entitlementId);
|
|
4605
4776
|
if (!writeTier) return tier;
|
|
4606
4777
|
try {
|
|
4607
|
-
(
|
|
4778
|
+
(_a = analytics.setUserContext) == null ? void 0 : _a.call(analytics, { extra: { [PLAN_TIER_CONTEXT_KEY]: tier } });
|
|
4608
4779
|
} catch {
|
|
4609
4780
|
}
|
|
4610
4781
|
return tier;
|
|
4611
4782
|
};
|
|
4612
4783
|
const paywallShown = (offering, props) => {
|
|
4613
|
-
var
|
|
4784
|
+
var _a, _b;
|
|
4614
4785
|
const shown = {
|
|
4615
|
-
packages_count: (_b = (
|
|
4786
|
+
packages_count: (_b = (_a = offering == null ? void 0 : offering.availablePackages) == null ? void 0 : _a.length) != null ? _b : 0
|
|
4616
4787
|
};
|
|
4617
4788
|
if (typeof (offering == null ? void 0 : offering.identifier) === "string") shown.offering_id = offering.identifier;
|
|
4618
4789
|
emit(WIRE_PURCHASE_EVENTS.paywallShown, { ...shown, ...props });
|
|
@@ -4666,10 +4837,10 @@ var resetSessionStartGuard = () => {
|
|
|
4666
4837
|
_emitted.clear();
|
|
4667
4838
|
};
|
|
4668
4839
|
var reportSessionStart = (opts) => {
|
|
4669
|
-
var
|
|
4840
|
+
var _a;
|
|
4670
4841
|
const target = opts.target;
|
|
4671
4842
|
if (!opts.sink && !(target == null ? void 0 : target.serverUrl)) return;
|
|
4672
|
-
const sessionId = (
|
|
4843
|
+
const sessionId = (_a = opts.sessionId) != null ? _a : makeSessionId();
|
|
4673
4844
|
setCurrentSessionId(sessionId);
|
|
4674
4845
|
if (opts.once !== false) {
|
|
4675
4846
|
if (_emitted.has(sessionId)) return;
|
|
@@ -4719,9 +4890,9 @@ var reportSessionStart = (opts) => {
|
|
|
4719
4890
|
};
|
|
4720
4891
|
var BACKGROUND_SESSION_MS = 30 * 60 * 1e3;
|
|
4721
4892
|
var useSessionStart = (config, options = {}) => {
|
|
4722
|
-
const latest =
|
|
4893
|
+
const latest = React19.useRef({ config, options });
|
|
4723
4894
|
latest.current = { config, options };
|
|
4724
|
-
|
|
4895
|
+
React19.useEffect(() => {
|
|
4725
4896
|
const resolveDeviceKey = (cfg, opts) => {
|
|
4726
4897
|
const host = typeof opts.deviceKey === "string" && opts.deviceKey.trim() ? opts.deviceKey : void 0;
|
|
4727
4898
|
if (host) return host;
|
|
@@ -4729,11 +4900,11 @@ var useSessionStart = (config, options = {}) => {
|
|
|
4729
4900
|
return resolveAutoDeviceKey({ appId: cfg.appId, storage: cfg.storage });
|
|
4730
4901
|
};
|
|
4731
4902
|
const fire = () => {
|
|
4732
|
-
var
|
|
4903
|
+
var _a, _b;
|
|
4733
4904
|
const { config: cfg, options: opts } = latest.current;
|
|
4734
4905
|
if (!(cfg == null ? void 0 : cfg.serverUrl)) return;
|
|
4735
4906
|
if (opts.enabled === false) return;
|
|
4736
|
-
const target = { serverUrl: cfg.serverUrl, apiKey: (
|
|
4907
|
+
const target = { serverUrl: cfg.serverUrl, apiKey: (_a = cfg.apiKey) != null ? _a : "" };
|
|
4737
4908
|
const device = collectDeviceContext();
|
|
4738
4909
|
if (cfg.appVersion) device.appVersion = cfg.appVersion;
|
|
4739
4910
|
reportSessionStart({
|
|
@@ -4784,7 +4955,7 @@ var resetFirstOpenLatch = () => {
|
|
|
4784
4955
|
_firstOpenLatched.clear();
|
|
4785
4956
|
};
|
|
4786
4957
|
var buildLifecycleEvent = (questionKey, opts) => {
|
|
4787
|
-
var
|
|
4958
|
+
var _a;
|
|
4788
4959
|
const userContext = {};
|
|
4789
4960
|
if (opts.deviceKey) userContext.device_key = opts.deviceKey;
|
|
4790
4961
|
if (typeof opts.sessionCount === "number" && Number.isFinite(opts.sessionCount)) {
|
|
@@ -4796,7 +4967,7 @@ var buildLifecycleEvent = (questionKey, opts) => {
|
|
|
4796
4967
|
const event = {
|
|
4797
4968
|
event_type: "app_event",
|
|
4798
4969
|
question_key: questionKey,
|
|
4799
|
-
session_id: (
|
|
4970
|
+
session_id: (_a = opts.sessionId) != null ? _a : makeSessionId()
|
|
4800
4971
|
};
|
|
4801
4972
|
const userId = sanitizeUserId(opts.userId);
|
|
4802
4973
|
if (userId) event.user_id = userId;
|
|
@@ -4822,8 +4993,8 @@ var emitFirstOpen = (opts) => {
|
|
|
4822
4993
|
routeLifecycleEvent(buildLifecycleEvent(FIRST_OPEN_EVENT, opts), opts);
|
|
4823
4994
|
};
|
|
4824
4995
|
var reportFirstOpen = (opts) => {
|
|
4825
|
-
var
|
|
4826
|
-
const appId = (
|
|
4996
|
+
var _a;
|
|
4997
|
+
const appId = (_a = opts.appId) != null ? _a : "default";
|
|
4827
4998
|
if (_firstOpenLatched.has(appId)) return;
|
|
4828
4999
|
_firstOpenLatched.add(appId);
|
|
4829
5000
|
const storage = opts.storage;
|
|
@@ -4848,8 +5019,8 @@ var reportFirstOpen = (opts) => {
|
|
|
4848
5019
|
})();
|
|
4849
5020
|
};
|
|
4850
5021
|
var wireLifecycleEvents = (opts) => {
|
|
4851
|
-
var
|
|
4852
|
-
const sessionId = (
|
|
5022
|
+
var _a;
|
|
5023
|
+
const sessionId = (_a = opts.sessionId) != null ? _a : makeSessionId();
|
|
4853
5024
|
reportFirstOpen({ ...opts, sessionId });
|
|
4854
5025
|
reportSessionStart({
|
|
4855
5026
|
target: opts.target,
|
|
@@ -4898,10 +5069,11 @@ var claimQueueKey = (preferred, explicit) => {
|
|
|
4898
5069
|
);
|
|
4899
5070
|
return key;
|
|
4900
5071
|
};
|
|
5072
|
+
var READ_TIMED_OUT = /* @__PURE__ */ Symbol("wireai:storage-read-timeout");
|
|
4901
5073
|
var withTimeout4 = (p, ms) => {
|
|
4902
5074
|
let timer;
|
|
4903
5075
|
const timeout = new Promise((resolve) => {
|
|
4904
|
-
timer = setTimeout(() => resolve(
|
|
5076
|
+
timer = setTimeout(() => resolve(READ_TIMED_OUT), ms);
|
|
4905
5077
|
});
|
|
4906
5078
|
return Promise.race([p, timeout]).finally(() => clearTimeout(timer));
|
|
4907
5079
|
};
|
|
@@ -4926,10 +5098,10 @@ var parsePersisted2 = (raw) => {
|
|
|
4926
5098
|
}
|
|
4927
5099
|
};
|
|
4928
5100
|
var createEventQueue = (options) => {
|
|
4929
|
-
var
|
|
5101
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
4930
5102
|
const target = options.target;
|
|
4931
5103
|
const storage = options.storage;
|
|
4932
|
-
const defaultKey = (_b = options.storageKey) != null ? _b : `wireai:evtq:${(
|
|
5104
|
+
const defaultKey = (_b = options.storageKey) != null ? _b : `wireai:evtq:${(_a = options.appId) != null ? _a : "default"}`;
|
|
4933
5105
|
const key = storage ? claimQueueKey(defaultKey, options.storageKey !== void 0) : defaultKey;
|
|
4934
5106
|
const maxSize = (_c = options.maxSize) != null ? _c : DEFAULTS.maxSize;
|
|
4935
5107
|
const batchSize = (_d = options.batchSize) != null ? _d : DEFAULTS.batchSize;
|
|
@@ -4941,6 +5113,7 @@ var createEventQueue = (options) => {
|
|
|
4941
5113
|
let flushing = false;
|
|
4942
5114
|
let attempt = 0;
|
|
4943
5115
|
let retryTimer;
|
|
5116
|
+
let backlogUnread = false;
|
|
4944
5117
|
const resolveEnvelope = () => {
|
|
4945
5118
|
try {
|
|
4946
5119
|
return typeof options.envelope === "function" ? options.envelope() : options.envelope;
|
|
@@ -4949,14 +5122,14 @@ var createEventQueue = (options) => {
|
|
|
4949
5122
|
}
|
|
4950
5123
|
};
|
|
4951
5124
|
const stamp = (event) => {
|
|
4952
|
-
var
|
|
5125
|
+
var _a2;
|
|
4953
5126
|
const env = resolveEnvelope();
|
|
4954
5127
|
const stamped = { ...event };
|
|
4955
5128
|
if (stamped.ts === void 0) stamped.ts = Date.now();
|
|
4956
5129
|
if (!env) return stamped;
|
|
4957
5130
|
if (!stamped.device && env.device) stamped.device = env.device;
|
|
4958
5131
|
if (!stamped.session_id && env.sessionId) stamped.session_id = env.sessionId;
|
|
4959
|
-
const uc = { ...(
|
|
5132
|
+
const uc = { ...(_a2 = stamped.user_context) != null ? _a2 : {} };
|
|
4960
5133
|
if (env.appVersion && uc.app_version === void 0) uc.app_version = env.appVersion;
|
|
4961
5134
|
if (env.appBuild && uc.app_build === void 0) uc.app_build = env.appBuild;
|
|
4962
5135
|
if (env.networkType && uc.network_type === void 0) uc.network_type = env.networkType;
|
|
@@ -4965,6 +5138,7 @@ var createEventQueue = (options) => {
|
|
|
4965
5138
|
};
|
|
4966
5139
|
const persist = () => {
|
|
4967
5140
|
if (!storage) return;
|
|
5141
|
+
if (backlogUnread) return;
|
|
4968
5142
|
try {
|
|
4969
5143
|
if (pending.length === 0) {
|
|
4970
5144
|
void storage.removeItem(key).catch(() => {
|
|
@@ -4987,23 +5161,44 @@ var createEventQueue = (options) => {
|
|
|
4987
5161
|
return `__nosig_${nextId}_${Math.random()}`;
|
|
4988
5162
|
}
|
|
4989
5163
|
};
|
|
5164
|
+
const mergePersisted = (persistedItems) => {
|
|
5165
|
+
if (persistedItems.length === 0) return;
|
|
5166
|
+
const seen = new Set(pending.map((item) => item.sig));
|
|
5167
|
+
const restored = [];
|
|
5168
|
+
for (const persisted of persistedItems) {
|
|
5169
|
+
const sig = safeSig(persisted.event);
|
|
5170
|
+
if (seen.has(sig)) continue;
|
|
5171
|
+
seen.add(sig);
|
|
5172
|
+
restored.push({ id: nextId++, event: persisted.event, sig });
|
|
5173
|
+
}
|
|
5174
|
+
if (restored.length === 0) return;
|
|
5175
|
+
pending = [...restored, ...pending];
|
|
5176
|
+
enforceSizeCap();
|
|
5177
|
+
persist();
|
|
5178
|
+
};
|
|
4990
5179
|
const loadPromise = (async () => {
|
|
4991
5180
|
if (!storage) return;
|
|
4992
5181
|
try {
|
|
4993
|
-
const
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5003
|
-
|
|
5182
|
+
const read = Promise.resolve(storage.getItem(key));
|
|
5183
|
+
read.catch(() => {
|
|
5184
|
+
});
|
|
5185
|
+
const raced = await withTimeout4(read, READ_TIMEOUT_MS4);
|
|
5186
|
+
if (raced === READ_TIMED_OUT) {
|
|
5187
|
+
backlogUnread = true;
|
|
5188
|
+
warnInDev(
|
|
5189
|
+
`[wireai] the persisted analytics backlog at "${key}" took longer than ${READ_TIMEOUT_MS4}ms to read, so the queue started without it. The stored events are NOT discarded: writes are held back until the read lands, and the backlog is merged in then. If you see this on every cold start, your storage adapter is too slow to be on the launch path.`
|
|
5190
|
+
);
|
|
5191
|
+
void read.then((late) => {
|
|
5192
|
+
backlogUnread = false;
|
|
5193
|
+
mergePersisted(parsePersisted2(late));
|
|
5194
|
+
flush();
|
|
5195
|
+
}).catch(() => {
|
|
5196
|
+
backlogUnread = false;
|
|
5197
|
+
persist();
|
|
5198
|
+
});
|
|
5199
|
+
return;
|
|
5004
5200
|
}
|
|
5005
|
-
|
|
5006
|
-
persist();
|
|
5201
|
+
mergePersisted(parsePersisted2(raced));
|
|
5007
5202
|
} catch {
|
|
5008
5203
|
}
|
|
5009
5204
|
})();
|
|
@@ -5095,18 +5290,18 @@ var createEventQueue = (options) => {
|
|
|
5095
5290
|
|
|
5096
5291
|
// src/session-analytics/useLifecycleEvents.ts
|
|
5097
5292
|
var useLifecycleEvents = (config, options = {}) => {
|
|
5098
|
-
const latest =
|
|
5293
|
+
const latest = React19.useRef({ config, options });
|
|
5099
5294
|
latest.current = { config, options };
|
|
5100
|
-
const queueRef =
|
|
5101
|
-
|
|
5295
|
+
const queueRef = React19.useRef(void 0);
|
|
5296
|
+
React19.useEffect(() => {
|
|
5102
5297
|
const resolveSink = () => {
|
|
5103
|
-
var
|
|
5298
|
+
var _a, _b;
|
|
5104
5299
|
const { config: cfg, options: opts } = latest.current;
|
|
5105
5300
|
if (opts.sink) return opts.sink;
|
|
5106
5301
|
if (!(cfg == null ? void 0 : cfg.serverUrl)) return void 0;
|
|
5107
5302
|
if (!queueRef.current) {
|
|
5108
5303
|
queueRef.current = createEventQueue({
|
|
5109
|
-
target: { serverUrl: cfg.serverUrl, apiKey: (
|
|
5304
|
+
target: { serverUrl: cfg.serverUrl, apiKey: (_a = cfg.apiKey) != null ? _a : "" },
|
|
5110
5305
|
storage: cfg.storage,
|
|
5111
5306
|
// Dedicated key so the hook's internal queue never collides with a host's main queue.
|
|
5112
5307
|
storageKey: `wireai:evtq:lifecycle:${(_b = cfg.appId) != null ? _b : "default"}`,
|
|
@@ -5116,24 +5311,24 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
5116
5311
|
return queueRef.current.enqueue;
|
|
5117
5312
|
};
|
|
5118
5313
|
const targetOf = (cfg) => {
|
|
5119
|
-
var
|
|
5120
|
-
return (cfg == null ? void 0 : cfg.serverUrl) ? { serverUrl: cfg.serverUrl, apiKey: (
|
|
5314
|
+
var _a;
|
|
5315
|
+
return (cfg == null ? void 0 : cfg.serverUrl) ? { serverUrl: cfg.serverUrl, apiKey: (_a = cfg.apiKey) != null ? _a : "" } : void 0;
|
|
5121
5316
|
};
|
|
5122
5317
|
const resolveDeviceKey = (cfg, opts) => {
|
|
5123
|
-
var
|
|
5124
|
-
const host = (
|
|
5318
|
+
var _a;
|
|
5319
|
+
const host = (_a = resolveIdentity({
|
|
5125
5320
|
value: opts.deviceKey,
|
|
5126
5321
|
space: "device",
|
|
5127
5322
|
source: "host",
|
|
5128
5323
|
scope: cfg == null ? void 0 : cfg.appId
|
|
5129
|
-
})) == null ? void 0 :
|
|
5324
|
+
})) == null ? void 0 : _a.value;
|
|
5130
5325
|
if (host) return host;
|
|
5131
5326
|
if (!(cfg == null ? void 0 : cfg.storage)) return void 0;
|
|
5132
5327
|
return resolveAutoDeviceKey({ appId: cfg.appId, storage: cfg.storage });
|
|
5133
5328
|
};
|
|
5134
5329
|
const mountOpenSessionId = makeSessionId();
|
|
5135
5330
|
const fireSession = (sessionId) => {
|
|
5136
|
-
var
|
|
5331
|
+
var _a;
|
|
5137
5332
|
const { config: cfg, options: opts } = latest.current;
|
|
5138
5333
|
if (opts.enabled === false) return;
|
|
5139
5334
|
if (!(cfg == null ? void 0 : cfg.serverUrl) && !opts.sink) return;
|
|
@@ -5146,14 +5341,14 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
5146
5341
|
userId: opts.userId,
|
|
5147
5342
|
deviceKey: resolveDeviceKey(cfg, opts),
|
|
5148
5343
|
sessionCount: opts.sessionCount,
|
|
5149
|
-
appVersion: (
|
|
5344
|
+
appVersion: (_a = cfg == null ? void 0 : cfg.appVersion) != null ? _a : device.appVersion,
|
|
5150
5345
|
platform: reactNative.Platform.OS,
|
|
5151
5346
|
device,
|
|
5152
5347
|
meta: opts.meta
|
|
5153
5348
|
});
|
|
5154
5349
|
};
|
|
5155
5350
|
const fireMountOpen = () => {
|
|
5156
|
-
var
|
|
5351
|
+
var _a;
|
|
5157
5352
|
fireSession(mountOpenSessionId);
|
|
5158
5353
|
const { config: cfg, options: opts } = latest.current;
|
|
5159
5354
|
if (opts.enabled === false) return;
|
|
@@ -5168,7 +5363,7 @@ var useLifecycleEvents = (config, options = {}) => {
|
|
|
5168
5363
|
userId: opts.userId,
|
|
5169
5364
|
deviceKey: resolveDeviceKey(cfg, opts),
|
|
5170
5365
|
sessionCount: opts.sessionCount,
|
|
5171
|
-
appVersion: (
|
|
5366
|
+
appVersion: (_a = cfg == null ? void 0 : cfg.appVersion) != null ? _a : device.appVersion,
|
|
5172
5367
|
platform: reactNative.Platform.OS,
|
|
5173
5368
|
device,
|
|
5174
5369
|
meta: opts.meta
|
|
@@ -5213,22 +5408,29 @@ exports.CenteredModal = CenteredModal;
|
|
|
5213
5408
|
exports.ChipSelectCard = ChipSelectCard;
|
|
5214
5409
|
exports.CompletionView = CompletionView;
|
|
5215
5410
|
exports.DEFAULT_FEATURES_TTL_MS = DEFAULT_FEATURES_TTL_MS;
|
|
5411
|
+
exports.DEFAULT_PERMISSION_COPY = DEFAULT_PERMISSION_COPY;
|
|
5412
|
+
exports.DEFAULT_PERMISSION_PLACEMENT = DEFAULT_PERMISSION_PLACEMENT;
|
|
5216
5413
|
exports.DEFAULT_SESSION_TTL_MS = DEFAULT_SESSION_TTL_MS;
|
|
5217
5414
|
exports.DemoOnboarding = DemoOnboarding;
|
|
5218
5415
|
exports.EXTRA_KEY_PREFIX = EXTRA_KEY_PREFIX;
|
|
5219
5416
|
exports.ErrorBlock = ErrorBlock;
|
|
5220
5417
|
exports.FIRST_OPEN_EVENT = FIRST_OPEN_EVENT;
|
|
5418
|
+
exports.GENERIC_PERMISSION_COPY = GENERIC_PERMISSION_COPY;
|
|
5221
5419
|
exports.IconRegistryProvider = IconRegistryProvider;
|
|
5222
5420
|
exports.IllustrationProvider = IllustrationProvider;
|
|
5223
5421
|
exports.InterstitialCard = InterstitialCard;
|
|
5224
5422
|
exports.LoadingBlock = LoadingBlock;
|
|
5225
5423
|
exports.LoadingScreen = LoadingScreen;
|
|
5424
|
+
exports.NOTIFICATIONS_PERMISSION_COPY = NOTIFICATIONS_PERMISSION_COPY;
|
|
5226
5425
|
exports.NumberStepperCard = NumberStepperCard;
|
|
5227
5426
|
exports.OnboardingButton = Button;
|
|
5228
5427
|
exports.OnboardingFlow = OnboardingFlow;
|
|
5229
5428
|
exports.OnboardingScaffold = OnboardingScaffold;
|
|
5230
5429
|
exports.OnboardingThemeProvider = OnboardingThemeProvider;
|
|
5430
|
+
exports.PERMISSION_CARD_NAME = PERMISSION_CARD_NAME;
|
|
5231
5431
|
exports.PLAN_TIER_CONTEXT_KEY = PLAN_TIER_CONTEXT_KEY;
|
|
5432
|
+
exports.PermissionCard = PermissionCard;
|
|
5433
|
+
exports.PermissionCardView = PermissionCardView;
|
|
5232
5434
|
exports.SESSION_STARTED_EVENT = SESSION_STARTED_EVENT;
|
|
5233
5435
|
exports.SelectionCard = SelectionCard;
|
|
5234
5436
|
exports.StatusCard = StatusCard;
|
|
@@ -5239,6 +5441,7 @@ exports.WIRE_ENV_VARS = WIRE_ENV_VARS;
|
|
|
5239
5441
|
exports.WIRE_ICON_GLYPHS = WIRE_ICON_GLYPHS;
|
|
5240
5442
|
exports.WIRE_ICON_NAMES = WIRE_ICON_NAMES;
|
|
5241
5443
|
exports.WIRE_ONBOARDING_EVENTS = WIRE_ONBOARDING_EVENTS;
|
|
5444
|
+
exports.WIRE_PERMISSION_EVENTS = WIRE_PERMISSION_EVENTS;
|
|
5242
5445
|
exports.WIRE_PURCHASE_EVENTS = WIRE_PURCHASE_EVENTS;
|
|
5243
5446
|
exports.WireFeaturesProvider = WireFeaturesProvider;
|
|
5244
5447
|
exports.WireIcon = WireIcon;
|
|
@@ -5250,6 +5453,7 @@ exports.attributionMetadata = attributionMetadata;
|
|
|
5250
5453
|
exports.bumpActivationRevalidation = bumpActivationRevalidation;
|
|
5251
5454
|
exports.clearPersistedSession = clearPersistedSession;
|
|
5252
5455
|
exports.clearPiiFromContext = clearPiiFromContext;
|
|
5456
|
+
exports.clearSettledPermissions = clearSettledPermissions;
|
|
5253
5457
|
exports.clearUserContext = clearUserContext;
|
|
5254
5458
|
exports.collectDeviceContext = collectDeviceContext;
|
|
5255
5459
|
exports.createRevenueCatBridge = createRevenueCatBridge;
|
|
@@ -5278,9 +5482,11 @@ exports.hydrateDeviceIdentity = hydrateDeviceIdentity;
|
|
|
5278
5482
|
exports.identifyOnboarding = identifyOnboarding;
|
|
5279
5483
|
exports.isFeaturesFresh = isFeaturesFresh;
|
|
5280
5484
|
exports.isOnboardingEnabled = isOnboardingEnabled;
|
|
5485
|
+
exports.isPermissionDue = isPermissionDue;
|
|
5281
5486
|
exports.isUserCancelled = isUserCancelled;
|
|
5282
5487
|
exports.isWireScalar = isWireScalar;
|
|
5283
5488
|
exports.loadPersistedSession = loadPersistedSession;
|
|
5489
|
+
exports.loadSettledPermissions = loadSettledPermissions;
|
|
5284
5490
|
exports.looksLikeEmail = looksLikeEmail;
|
|
5285
5491
|
exports.lookupIconGlyph = lookupIconGlyph;
|
|
5286
5492
|
exports.makeSessionId = makeSessionId;
|
|
@@ -5288,11 +5494,18 @@ exports.mergeTheme = mergeTheme;
|
|
|
5288
5494
|
exports.mintDeviceId = mintDeviceId;
|
|
5289
5495
|
exports.motionSpec = motionSpec_exports;
|
|
5290
5496
|
exports.namespaceExtra = namespaceExtra;
|
|
5497
|
+
exports.normalizeAfterCard = normalizeAfterCard;
|
|
5498
|
+
exports.normalizePermissionStatus = normalizePermissionStatus;
|
|
5291
5499
|
exports.onboardingComponents = onboardingComponents;
|
|
5292
5500
|
exports.parseWireFeatures = parseWireFeatures;
|
|
5293
5501
|
exports.peekPersistedSession = peekPersistedSession;
|
|
5502
|
+
exports.permissionEventName = permissionEventName;
|
|
5503
|
+
exports.permissionEventProps = permissionEventProps;
|
|
5504
|
+
exports.permissionScreenId = permissionScreenId;
|
|
5505
|
+
exports.permissionStorageKey = permissionStorageKey;
|
|
5294
5506
|
exports.readCachedFeatures = readCachedFeatures;
|
|
5295
5507
|
exports.readProgress = readProgress;
|
|
5508
|
+
exports.readSettledPermissions = readSettledPermissions;
|
|
5296
5509
|
exports.reportClientEvent = reportClientEvent;
|
|
5297
5510
|
exports.reportClientEventAwait = reportClientEventAwait;
|
|
5298
5511
|
exports.reportClientEvents = reportClientEvents;
|
|
@@ -5307,10 +5520,13 @@ exports.resetIdentityProvenance = resetIdentityProvenance;
|
|
|
5307
5520
|
exports.resetSessionStartGuard = resetSessionStartGuard;
|
|
5308
5521
|
exports.resolveAutoDeviceKey = resolveAutoDeviceKey;
|
|
5309
5522
|
exports.resolveIdentity = resolveIdentity;
|
|
5523
|
+
exports.resolvePermissionCopy = resolvePermissionCopy;
|
|
5310
5524
|
exports.resolvePlanTier = resolvePlanTier;
|
|
5311
5525
|
exports.resolveUserContext = resolveUserContext;
|
|
5312
5526
|
exports.sanitizeUserId = sanitizeUserId;
|
|
5313
5527
|
exports.savePersistedSession = savePersistedSession;
|
|
5528
|
+
exports.saveSettledPermissions = saveSettledPermissions;
|
|
5529
|
+
exports.selectDuePermissionScreen = selectDuePermissionScreen;
|
|
5314
5530
|
exports.sessionStorageKey = sessionStorageKey;
|
|
5315
5531
|
exports.setCurrentSessionId = setCurrentSessionId;
|
|
5316
5532
|
exports.subscribeActivationRevalidation = subscribeActivationRevalidation;
|