@mrrocket/sdk 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -1
- package/dist/browser/mrrocket-flows.js +9 -2
- package/dist/browser/mrrocket-messenger.js +3 -3
- package/dist/browser/mrrocket.js +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +2 -1
- package/dist/browser.js.map +1 -1
- package/dist/client.d.ts +23 -3
- package/dist/client.js +15 -1
- package/dist/client.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.js.map +1 -1
- package/dist/core.d.ts +3 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/finish-web.d.ts +18 -0
- package/dist/finish-web.js +139 -0
- package/dist/finish-web.js.map +1 -0
- package/dist/flows-ui.d.ts +1 -10
- package/dist/flows-ui.js +105 -6
- package/dist/flows-ui.js.map +1 -1
- package/dist/flows-web.d.ts +8 -1
- package/dist/flows-web.js +8 -0
- package/dist/flows-web.js.map +1 -1
- package/dist/flows.d.ts +159 -7
- package/dist/flows.js +240 -28
- package/dist/flows.js.map +1 -1
- package/dist/icons.d.ts +24 -0
- package/dist/icons.js +61 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/messenger-ui.js +78 -53
- package/dist/messenger-ui.js.map +1 -1
- package/dist/onboarding-state.d.ts +23 -0
- package/dist/onboarding-state.js +43 -0
- package/dist/onboarding-state.js.map +1 -0
- package/dist/react-native/index.d.cts +177 -15
- package/dist/react-native/index.d.ts +177 -15
- package/dist/react-native/index.js +776 -270
- package/dist/react-native/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -48,10 +48,10 @@ __export(native_exports, {
|
|
|
48
48
|
useVariant: () => useVariant
|
|
49
49
|
});
|
|
50
50
|
module.exports = __toCommonJS(native_exports);
|
|
51
|
-
var
|
|
51
|
+
var import_react4 = require("react");
|
|
52
52
|
|
|
53
53
|
// src/core.ts
|
|
54
|
-
var SDK_VERSION = "0.
|
|
54
|
+
var SDK_VERSION = "0.18.0";
|
|
55
55
|
var propOf = (person, name) => {
|
|
56
56
|
const want = name.trim().toLowerCase();
|
|
57
57
|
for (const [k, v] of Object.entries(person)) if (k.toLowerCase() === want) return v;
|
|
@@ -173,6 +173,46 @@ var textChanges = (config, distinctId, preview) => {
|
|
|
173
173
|
};
|
|
174
174
|
var newDistinctId = () => typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `ck_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
175
175
|
|
|
176
|
+
// src/onboarding-state.ts
|
|
177
|
+
var import_react = require("react");
|
|
178
|
+
var none = [];
|
|
179
|
+
var useOnboardingItem = (flows, id, start) => {
|
|
180
|
+
const [state, setState] = (0, import_react.useState)(() => flows && id ? flows.onboarding.item(id) : null);
|
|
181
|
+
(0, import_react.useEffect)(() => {
|
|
182
|
+
if (!flows || !id) {
|
|
183
|
+
setState(null);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const up = () => {
|
|
187
|
+
const s = flows.onboarding.item(id);
|
|
188
|
+
setState(s);
|
|
189
|
+
if (s && !s.done && !s.dismissed) flows.onboarding.seen(id);
|
|
190
|
+
};
|
|
191
|
+
up();
|
|
192
|
+
return flows.subscribe(up);
|
|
193
|
+
}, [flows, id]);
|
|
194
|
+
return (0, import_react.useMemo)(
|
|
195
|
+
() => ({
|
|
196
|
+
item: state?.item ?? null,
|
|
197
|
+
steps: state?.steps ?? none,
|
|
198
|
+
done: !!state?.done,
|
|
199
|
+
dismissed: !!state?.dismissed,
|
|
200
|
+
eligible: !!state?.eligible,
|
|
201
|
+
complete: (stepId) => {
|
|
202
|
+
if (flows && id) flows.onboarding.complete(id, stepId);
|
|
203
|
+
},
|
|
204
|
+
dismiss: () => {
|
|
205
|
+
if (flows && id) flows.onboarding.dismissItem(id);
|
|
206
|
+
},
|
|
207
|
+
answer: (question, value) => {
|
|
208
|
+
if (flows && id) flows.onboarding.answerItem(id, question, value);
|
|
209
|
+
},
|
|
210
|
+
start
|
|
211
|
+
}),
|
|
212
|
+
[state, flows, id, start]
|
|
213
|
+
);
|
|
214
|
+
};
|
|
215
|
+
|
|
176
216
|
// src/identity.ts
|
|
177
217
|
var UNSIGNED_HELP = "401: sign the user id on your server with userHash(id) from @mrrocket/sdk/next/server and pass identify(id, props, { hash }).";
|
|
178
218
|
var warnUnsigned = (status, log = (m) => console.warn(m)) => {
|
|
@@ -359,7 +399,21 @@ var matchesTrigger = (trigger, event) => {
|
|
|
359
399
|
};
|
|
360
400
|
var startsOnLoad = (trigger) => /^(first (launch|visit|open|session|login|sign ?in|app open)|app (opened|launched)|on load|every visit|always)?$/i.test(trigger.trim());
|
|
361
401
|
var isPageTrigger = (trigger) => trigger.trim().startsWith("/");
|
|
362
|
-
var
|
|
402
|
+
var NEEDS_NEWER = "Needs tracking code 0.18.0";
|
|
403
|
+
var momentOf = (f) => f.when ?? f.trigger;
|
|
404
|
+
var manual = (trigger) => eventSlug(trigger) === "from_a_checklist" || eventSlug(trigger) === "from_your_code" || eventSlug(trigger) === eventSlug(NEEDS_NEWER);
|
|
405
|
+
var AFTER_PREFIX = "after:";
|
|
406
|
+
var afterOf = (trigger) => {
|
|
407
|
+
const t = (trigger ?? "").trim();
|
|
408
|
+
return t.toLowerCase().startsWith(AFTER_PREFIX) ? t.slice(AFTER_PREFIX.length).trim() || null : null;
|
|
409
|
+
};
|
|
410
|
+
var opensOf = (step) => step.opens ?? (step.startsTour ? { kind: "tour", id: step.startsTour } : void 0);
|
|
411
|
+
var answerOk = (q, value) => {
|
|
412
|
+
if (!q || value == null) return false;
|
|
413
|
+
if (q.type === "choice") return (q.options ?? []).some((o) => o.id === value);
|
|
414
|
+
return value.trim().length > 0 && value.length <= 500;
|
|
415
|
+
};
|
|
416
|
+
var answerLabel = (q, value) => q?.type === "choice" ? q.options?.find((o) => o.id === value)?.label ?? value : value.trim();
|
|
363
417
|
var videoEmbed = (url) => {
|
|
364
418
|
const u = (url ?? "").trim();
|
|
365
419
|
if (!/^https?:\/\//i.test(u)) return null;
|
|
@@ -425,7 +479,12 @@ var createFlows = (env) => {
|
|
|
425
479
|
const now = () => env.now?.() ?? Date.now();
|
|
426
480
|
let timer = null;
|
|
427
481
|
let returnTo = null;
|
|
482
|
+
const answers = /* @__PURE__ */ new Map();
|
|
483
|
+
const drafts = /* @__PURE__ */ new Map();
|
|
484
|
+
const celebrated = /* @__PURE__ */ new Set();
|
|
485
|
+
let finaleNow = null;
|
|
428
486
|
const flows = () => config?.onboarding ?? [];
|
|
487
|
+
const drawn = () => flows().filter((f) => f.shownBy !== "code");
|
|
429
488
|
const flowById = (id) => id ? flows().find((f) => f.id === id) : void 0;
|
|
430
489
|
const prog = (id) => {
|
|
431
490
|
let p = progress.get(id);
|
|
@@ -499,6 +558,14 @@ var createFlows = (env) => {
|
|
|
499
558
|
};
|
|
500
559
|
const keyOf = (pid) => `${PROGRESS_KEY}:${pid ?? "visitor"}`;
|
|
501
560
|
const eventsKeyOf = (pid) => `${PROGRESS_KEY}:events:${pid ?? "visitor"}`;
|
|
561
|
+
const answersKeyOf = (pid) => `${PROGRESS_KEY}:answers:${pid ?? "visitor"}`;
|
|
562
|
+
const celebrate = (f) => {
|
|
563
|
+
if (!f.finish || f.finish === "none" || f.shownBy === "code" || celebrated.has(f.id)) return;
|
|
564
|
+
const p = progress.get(f.id);
|
|
565
|
+
if (!p || p.dismissed || walkLine(f, nodesOf(f), p, false).at !== "end") return;
|
|
566
|
+
celebrated.add(f.id);
|
|
567
|
+
finaleNow = { kind: f.finish, key: `${f.id}:${now()}` };
|
|
568
|
+
};
|
|
502
569
|
const save = () => {
|
|
503
570
|
dirty = false;
|
|
504
571
|
const store = env.storage?.();
|
|
@@ -514,6 +581,7 @@ var createFlows = (env) => {
|
|
|
514
581
|
};
|
|
515
582
|
try {
|
|
516
583
|
store.set(keyOf(env.personId()), JSON.stringify(out));
|
|
584
|
+
if (answers.size) store.set(answersKeyOf(env.personId()), JSON.stringify(Object.fromEntries(answers)));
|
|
517
585
|
if (seenEvents.size) store.set(eventsKeyOf(env.personId()), JSON.stringify([...seenEvents].slice(-200)));
|
|
518
586
|
} catch {
|
|
519
587
|
}
|
|
@@ -566,8 +634,17 @@ var createFlows = (env) => {
|
|
|
566
634
|
type: "checklist",
|
|
567
635
|
flow,
|
|
568
636
|
items: items.map((s) => {
|
|
569
|
-
const
|
|
570
|
-
|
|
637
|
+
const o = opensOf(s);
|
|
638
|
+
const t = o && (o.kind === "tour" || o.kind === "modal") && o.id !== flow.id ? flowById(o.id) : void 0;
|
|
639
|
+
const target = t && t.shownBy !== "code" && nodesOf(t).length ? t : void 0;
|
|
640
|
+
const opens = o && (o.kind === "page" ? !!o.target.trim() : o.kind === "code" || !!target) ? o : void 0;
|
|
641
|
+
return {
|
|
642
|
+
step: s,
|
|
643
|
+
done: p.done.has(s.id),
|
|
644
|
+
...target && o?.kind === "tour" ? { tour: target } : {},
|
|
645
|
+
...opens ? { opens } : {},
|
|
646
|
+
...target ? { target } : {}
|
|
647
|
+
};
|
|
571
648
|
})
|
|
572
649
|
};
|
|
573
650
|
}
|
|
@@ -578,7 +655,16 @@ var createFlows = (env) => {
|
|
|
578
655
|
const rest = line.slice(index + 1);
|
|
579
656
|
const fork = rest.findIndex((n) => n.kind === "condition");
|
|
580
657
|
const ahead = (fork < 0 ? rest : rest.slice(0, fork)).filter(isStep).length;
|
|
581
|
-
return {
|
|
658
|
+
return {
|
|
659
|
+
type: "step",
|
|
660
|
+
flow,
|
|
661
|
+
step,
|
|
662
|
+
index: w.before,
|
|
663
|
+
total: w.before + 1 + ahead,
|
|
664
|
+
last: !ahead && fork < 0,
|
|
665
|
+
// 0.18.0: a question's answer so far, and whether there is one before it to go back to.
|
|
666
|
+
...step.kind === "question" ? { answer: drafts.get(step.id) ?? (step.question ? answers.get(step.question.key) : void 0), back: w.before > 0 } : {}
|
|
667
|
+
};
|
|
582
668
|
};
|
|
583
669
|
const view = () => {
|
|
584
670
|
if (cancel) {
|
|
@@ -605,23 +691,25 @@ var createFlows = (env) => {
|
|
|
605
691
|
if (ob) return ob;
|
|
606
692
|
if (active && !holding) {
|
|
607
693
|
const back = returnTo;
|
|
608
|
-
const
|
|
694
|
+
const ended2 = active;
|
|
609
695
|
returnTo = null;
|
|
610
696
|
active = null;
|
|
611
697
|
const list = back ? flowById(back.flow) : void 0;
|
|
612
698
|
if (back && list) {
|
|
613
699
|
const item = stepsIn(nodesOf(list)).find((s) => s.id === back.step);
|
|
614
700
|
const p = prog(list.id);
|
|
615
|
-
if (item && !item.event && !progress.get(
|
|
701
|
+
if (item && !item.event && !progress.get(ended2)?.dismissed && !p.done.has(item.id)) {
|
|
616
702
|
markDone(p, item.id);
|
|
617
703
|
record({ flow: list.id, step: item.id, kind: "checklist", action: "completed" });
|
|
704
|
+
celebrate(list);
|
|
618
705
|
}
|
|
619
706
|
active = list.id;
|
|
620
707
|
const again = onboardingView();
|
|
621
708
|
if (again) return again;
|
|
622
709
|
if (!holding) active = null;
|
|
623
710
|
} else if (known) {
|
|
624
|
-
const
|
|
711
|
+
const was = flowById(ended2);
|
|
712
|
+
const after = was ? momentOf(was) : void 0;
|
|
625
713
|
Promise.resolve().then(() => autoStart(after));
|
|
626
714
|
}
|
|
627
715
|
}
|
|
@@ -649,22 +737,64 @@ var createFlows = (env) => {
|
|
|
649
737
|
emit();
|
|
650
738
|
return true;
|
|
651
739
|
};
|
|
652
|
-
const allowed = (f) => f.audience !== "signed_in" || !!env.personId();
|
|
740
|
+
const allowed = (f) => f.audience === "answered" ? !!f.answered && answers.get(f.answered.question) === f.answered.option : f.audience !== "signed_in" || !!env.personId();
|
|
741
|
+
const predecessorEnded = (id) => {
|
|
742
|
+
const g = flowById(id);
|
|
743
|
+
return !g || finished(g);
|
|
744
|
+
};
|
|
745
|
+
const due = (f, trigger = momentOf(f)) => {
|
|
746
|
+
const path = env.path?.();
|
|
747
|
+
const pred = afterOf(trigger);
|
|
748
|
+
if (pred) return predecessorEnded(pred);
|
|
749
|
+
if (manual(trigger)) return false;
|
|
750
|
+
if (isPageTrigger(trigger)) return path !== void 0 && pageMatches(trigger, path);
|
|
751
|
+
if (startsOnLoad(trigger)) return true;
|
|
752
|
+
for (const e of seenEvents) if (matchesTrigger(trigger, e)) return true;
|
|
753
|
+
return false;
|
|
754
|
+
};
|
|
653
755
|
const autoStart = (after) => {
|
|
654
756
|
if (!auto || active || !known) return;
|
|
655
757
|
if (!env.personId() && !env.storage?.()) return;
|
|
656
758
|
const path = env.path?.();
|
|
657
759
|
const same2 = after && !manual(after) ? eventSlug(after) : "";
|
|
658
|
-
const next =
|
|
659
|
-
(f) => (isPageTrigger(f
|
|
760
|
+
const next = drawn().find(
|
|
761
|
+
(f) => (afterOf(momentOf(f)) ? predecessorEnded(afterOf(momentOf(f))) : isPageTrigger(momentOf(f)) ? path !== void 0 && pageMatches(momentOf(f), path) : startsOnLoad(momentOf(f)) || !!same2 && eventSlug(momentOf(f)) === same2) && allowed(f) && nodesOf(f).length && !finished(f)
|
|
660
762
|
);
|
|
661
763
|
if (next) start(next);
|
|
662
764
|
};
|
|
765
|
+
const openItem = (list, stepId, target) => {
|
|
766
|
+
const p = prog(target.id);
|
|
767
|
+
p.done.clear();
|
|
768
|
+
p.at.clear();
|
|
769
|
+
p.dismissed = false;
|
|
770
|
+
returnTo = { flow: list.id, step: stepId };
|
|
771
|
+
active = target.id;
|
|
772
|
+
env.track(ONBOARDING_EVENT, { flow: target.id, action: "started", from: list.id });
|
|
773
|
+
save();
|
|
774
|
+
emit();
|
|
775
|
+
};
|
|
776
|
+
const answerStep = (flow, step, raw) => {
|
|
777
|
+
const q = step.question;
|
|
778
|
+
const value = q.type === "text" ? raw.trim().slice(0, 500) : raw;
|
|
779
|
+
answers.set(q.key, value);
|
|
780
|
+
drafts.delete(step.id);
|
|
781
|
+
markDone(prog(flow.id), step.id);
|
|
782
|
+
env.track(ONBOARDING_EVENT, { flow: flow.id, step: step.id, kind: "question", action: "completed", question: q.key, answer: value, label: answerLabel(q, value) });
|
|
783
|
+
celebrate(flow);
|
|
784
|
+
save();
|
|
785
|
+
};
|
|
786
|
+
const ended = (f) => {
|
|
787
|
+
save();
|
|
788
|
+
if (finished(f)) Promise.resolve().then(() => autoStart());
|
|
789
|
+
emit();
|
|
790
|
+
};
|
|
663
791
|
const refresh = () => {
|
|
664
792
|
const pid = env.personId();
|
|
665
793
|
if (progressFor !== null && progressFor !== pid) {
|
|
666
794
|
progress.clear();
|
|
667
795
|
seenEvents.clear();
|
|
796
|
+
answers.clear();
|
|
797
|
+
drafts.clear();
|
|
668
798
|
handled.clear();
|
|
669
799
|
active = null;
|
|
670
800
|
returnTo = null;
|
|
@@ -681,6 +811,10 @@ var createFlows = (env) => {
|
|
|
681
811
|
if (seen) {
|
|
682
812
|
for (const e of JSON.parse(seen)) if (typeof e === "string") seenEvents.add(e);
|
|
683
813
|
}
|
|
814
|
+
const said = await store.get(answersKeyOf(pid));
|
|
815
|
+
if (said) {
|
|
816
|
+
for (const [k, v] of Object.entries(JSON.parse(said))) if (typeof v === "string") answers.set(k, v);
|
|
817
|
+
}
|
|
684
818
|
} catch {
|
|
685
819
|
}
|
|
686
820
|
}
|
|
@@ -691,6 +825,7 @@ var createFlows = (env) => {
|
|
|
691
825
|
if (state && env.personId() === pid) {
|
|
692
826
|
merge(state.onboarding);
|
|
693
827
|
for (const e of state.events ?? []) if (typeof e === "string") seenEvents.add(eventSlug(e));
|
|
828
|
+
for (const [k, v] of Object.entries(state.answers ?? {})) if (typeof v === "string" && !answers.has(k)) answers.set(k, v);
|
|
694
829
|
messages = (state.messages ?? []).filter((m) => m && m.id && m.title);
|
|
695
830
|
}
|
|
696
831
|
}
|
|
@@ -784,27 +919,33 @@ var createFlows = (env) => {
|
|
|
784
919
|
if (fresh) seenEvents.add(slug);
|
|
785
920
|
const flow = flowById(active);
|
|
786
921
|
let ticked = false;
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
922
|
+
const lists = [...flow ? [flow] : [], ...flows().filter((f) => f.shownBy === "code" && f.id !== flow?.id)];
|
|
923
|
+
for (const l of lists) {
|
|
924
|
+
const p = prog(l.id);
|
|
925
|
+
let here = false;
|
|
926
|
+
for (const s of stepsIn(nodesOf(l)))
|
|
790
927
|
if (s.kind === "checklist" && s.event && !p.done.has(s.id) && matchesTrigger(s.event, name)) {
|
|
791
928
|
markDone(p, s.id);
|
|
792
|
-
|
|
793
|
-
env.track(ONBOARDING_EVENT, { flow:
|
|
929
|
+
here = true;
|
|
930
|
+
env.track(ONBOARDING_EVENT, { flow: l.id, step: s.id, kind: s.kind, action: "completed" });
|
|
794
931
|
}
|
|
932
|
+
if (here) {
|
|
933
|
+
ticked = true;
|
|
934
|
+
celebrate(l);
|
|
935
|
+
}
|
|
795
936
|
}
|
|
796
|
-
if (ticked || fresh && flow) {
|
|
937
|
+
if (ticked || fresh && (flow || lists.length)) {
|
|
797
938
|
save();
|
|
798
939
|
emit();
|
|
799
940
|
} else if (fresh) save();
|
|
800
941
|
if (!auto || !env.personId() && !env.storage?.()) return;
|
|
801
|
-
const next =
|
|
942
|
+
const next = drawn().find((f) => nodesOf(f).length && !manual(momentOf(f)) && matchesTrigger(momentOf(f), name) && allowed(f) && !finished(f));
|
|
802
943
|
if (next) start(next);
|
|
803
944
|
},
|
|
804
945
|
openCancelFlow,
|
|
805
946
|
startOnboarding: (id) => {
|
|
806
|
-
const f = id ? flowById(id) :
|
|
807
|
-
if (!f || !nodesOf(f).length) return false;
|
|
947
|
+
const f = id ? flowById(id) : drawn().find((x) => nodesOf(x).length && !manual(momentOf(x)) && !afterOf(momentOf(x)) && !finished(x));
|
|
948
|
+
if (!f || !nodesOf(f).length || f.shownBy === "code") return false;
|
|
808
949
|
const p = prog(f.id);
|
|
809
950
|
p.dismissed = false;
|
|
810
951
|
return start(f);
|
|
@@ -895,8 +1036,17 @@ var createFlows = (env) => {
|
|
|
895
1036
|
next: () => {
|
|
896
1037
|
const v = onboardingView();
|
|
897
1038
|
if (v?.type !== "step") return;
|
|
1039
|
+
if (v.step.kind === "question") {
|
|
1040
|
+
const q = v.step.question;
|
|
1041
|
+
const a = drafts.get(v.step.id) ?? (q ? answers.get(q.key) : void 0);
|
|
1042
|
+
if (!q || !answerOk(q, a)) return;
|
|
1043
|
+
answerStep(v.flow, v.step, a);
|
|
1044
|
+
emit();
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
898
1047
|
markDone(prog(v.flow.id), v.step.id);
|
|
899
1048
|
env.track(ONBOARDING_EVENT, { flow: v.flow.id, step: v.step.id, kind: v.step.kind, action: "completed" });
|
|
1049
|
+
celebrate(v.flow);
|
|
900
1050
|
save();
|
|
901
1051
|
emit();
|
|
902
1052
|
const url = v.step.kind === "modal" ? safeUrl(v.step.url) : void 0;
|
|
@@ -909,6 +1059,7 @@ var createFlows = (env) => {
|
|
|
909
1059
|
if (!item || item.done) return;
|
|
910
1060
|
markDone(prog(v.flow.id), stepId);
|
|
911
1061
|
env.track(ONBOARDING_EVENT, { flow: v.flow.id, step: stepId, kind: "checklist", action: "completed" });
|
|
1062
|
+
celebrate(v.flow);
|
|
912
1063
|
save();
|
|
913
1064
|
emit();
|
|
914
1065
|
},
|
|
@@ -925,20 +1076,112 @@ var createFlows = (env) => {
|
|
|
925
1076
|
startTour: (stepId) => {
|
|
926
1077
|
const v = onboardingView();
|
|
927
1078
|
if (v?.type !== "checklist") return false;
|
|
928
|
-
const
|
|
929
|
-
if (!
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1079
|
+
const target = v.items.find((i) => i.step.id === stepId)?.target;
|
|
1080
|
+
if (!target) return false;
|
|
1081
|
+
openItem(v.flow, stepId, target);
|
|
1082
|
+
return true;
|
|
1083
|
+
},
|
|
1084
|
+
open: (stepId) => {
|
|
1085
|
+
const v = onboardingView();
|
|
1086
|
+
if (v?.type !== "checklist") return false;
|
|
1087
|
+
const it = v.items.find((i) => i.step.id === stepId);
|
|
1088
|
+
const o = it?.opens;
|
|
1089
|
+
if (!it || !o) return false;
|
|
1090
|
+
env.track(ONBOARDING_EVENT, { flow: v.flow.id, step: stepId, kind: "checklist", action: "opened", opens: o.kind });
|
|
1091
|
+
if ((o.kind === "tour" || o.kind === "modal") && it.target) {
|
|
1092
|
+
openItem(v.flow, stepId, it.target);
|
|
1093
|
+
return true;
|
|
1094
|
+
}
|
|
1095
|
+
if (!it.done && !it.step.event) {
|
|
1096
|
+
markDone(prog(v.flow.id), stepId);
|
|
1097
|
+
env.track(ONBOARDING_EVENT, { flow: v.flow.id, step: stepId, kind: "checklist", action: "completed" });
|
|
1098
|
+
celebrate(v.flow);
|
|
1099
|
+
}
|
|
937
1100
|
save();
|
|
938
1101
|
emit();
|
|
1102
|
+
if (o.kind === "page") env.navigate?.(o.target.trim());
|
|
1103
|
+
else env.task?.(stepId, v.flow);
|
|
939
1104
|
return true;
|
|
1105
|
+
},
|
|
1106
|
+
answer: (value) => {
|
|
1107
|
+
const v = onboardingView();
|
|
1108
|
+
if (v?.type !== "step" || v.step.kind !== "question") return;
|
|
1109
|
+
drafts.set(v.step.id, String(value).slice(0, 500));
|
|
1110
|
+
emit();
|
|
1111
|
+
},
|
|
1112
|
+
back: () => {
|
|
1113
|
+
const v = onboardingView();
|
|
1114
|
+
if (v?.type !== "step" || v.step.kind !== "question" || !v.back) return;
|
|
1115
|
+
const line = stepsIn(nodesOf(v.flow));
|
|
1116
|
+
const at = line.findIndex((s) => s.id === v.step.id);
|
|
1117
|
+
const p = prog(v.flow.id);
|
|
1118
|
+
for (let i = at - 1; i >= 0; i--)
|
|
1119
|
+
if (p.done.has(line[i].id)) {
|
|
1120
|
+
p.done.delete(line[i].id);
|
|
1121
|
+
p.at.delete(line[i].id);
|
|
1122
|
+
break;
|
|
1123
|
+
}
|
|
1124
|
+
save();
|
|
1125
|
+
emit();
|
|
1126
|
+
},
|
|
1127
|
+
item: (id) => {
|
|
1128
|
+
const f = flowById(id);
|
|
1129
|
+
if (!f) return null;
|
|
1130
|
+
const p = progress.get(f.id);
|
|
1131
|
+
const steps = stepsIn(nodesOf(f)).map((s) => {
|
|
1132
|
+
const a = s.question ? answers.get(s.question.key) : void 0;
|
|
1133
|
+
return { ...s, done: !!p?.done.has(s.id), ...a !== void 0 ? { answer: a } : {} };
|
|
1134
|
+
});
|
|
1135
|
+
const done = steps.length > 0 && steps.every((s) => s.done);
|
|
1136
|
+
const dismissed = !!p?.dismissed;
|
|
1137
|
+
return { item: f, steps, done, dismissed, eligible: !done && !dismissed && allowed(f) && due(f) };
|
|
1138
|
+
},
|
|
1139
|
+
seen: (id) => {
|
|
1140
|
+
const f = flowById(id);
|
|
1141
|
+
if (!f || f.shownBy !== "code" || !known) return;
|
|
1142
|
+
if (!shown.has(`f:${f.id}`)) {
|
|
1143
|
+
shown.add(`f:${f.id}`);
|
|
1144
|
+
env.track(ONBOARDING_EVENT, { flow: f.id, action: "started" });
|
|
1145
|
+
}
|
|
1146
|
+
const p = progress.get(f.id);
|
|
1147
|
+
for (const s of stepsIn(nodesOf(f)))
|
|
1148
|
+
if (!p?.done.has(s.id) && !shown.has(`s:${s.id}`)) {
|
|
1149
|
+
shown.add(`s:${s.id}`);
|
|
1150
|
+
env.track(ONBOARDING_EVENT, { flow: f.id, step: s.id, kind: s.kind, action: "shown" });
|
|
1151
|
+
if (s.kind !== "checklist") break;
|
|
1152
|
+
}
|
|
1153
|
+
},
|
|
1154
|
+
complete: (id, stepId) => {
|
|
1155
|
+
const f = flowById(id);
|
|
1156
|
+
const s = f && stepsIn(nodesOf(f)).find((x) => x.id === stepId);
|
|
1157
|
+
if (!f || !s || s.kind === "question") return;
|
|
1158
|
+
const p = prog(f.id);
|
|
1159
|
+
if (p.done.has(s.id)) return;
|
|
1160
|
+
markDone(p, s.id);
|
|
1161
|
+
env.track(ONBOARDING_EVENT, { flow: f.id, step: s.id, kind: s.kind, action: "completed" });
|
|
1162
|
+
ended(f);
|
|
1163
|
+
},
|
|
1164
|
+
dismissItem: (id) => {
|
|
1165
|
+
const f = flowById(id);
|
|
1166
|
+
if (!f) return;
|
|
1167
|
+
const p = prog(f.id);
|
|
1168
|
+
if (p.dismissed) return;
|
|
1169
|
+
p.dismissed = true;
|
|
1170
|
+
env.track(ONBOARDING_EVENT, { flow: f.id, action: "dismissed" });
|
|
1171
|
+
if (active === f.id) active = null;
|
|
1172
|
+
ended(f);
|
|
1173
|
+
},
|
|
1174
|
+
answerItem: (id, question, value) => {
|
|
1175
|
+
const f = flowById(id);
|
|
1176
|
+
const s = f && stepsIn(nodesOf(f)).find((x) => x.kind === "question" && (x.id === question || x.question?.key === question));
|
|
1177
|
+
if (!f || !s?.question || !answerOk(s.question, value)) return;
|
|
1178
|
+
answerStep(f, s, value);
|
|
1179
|
+
ended(f);
|
|
940
1180
|
}
|
|
941
1181
|
},
|
|
1182
|
+
finale: () => finaleNow,
|
|
1183
|
+
accent: () => config?.onboardingAccent,
|
|
1184
|
+
answers: () => Object.fromEntries(answers),
|
|
942
1185
|
message: {
|
|
943
1186
|
click: () => {
|
|
944
1187
|
const v = view();
|
|
@@ -1372,7 +1615,14 @@ var createClient = (options, deps) => {
|
|
|
1372
1615
|
set: (k, v) => void set(k, v)
|
|
1373
1616
|
} : null,
|
|
1374
1617
|
openUrl: deps.openUrl,
|
|
1375
|
-
fetchInApp: (id) => fetchInApp(id)
|
|
1618
|
+
fetchInApp: (id) => fetchInApp(id),
|
|
1619
|
+
// 0.18.0: a task's page or screen goes to the app's navigator; without one only a link with a scheme opens.
|
|
1620
|
+
navigate: (target) => {
|
|
1621
|
+
if (options.onNavigate) return options.onNavigate(target);
|
|
1622
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(target) && !/^(javascript|data|vbscript):/i.test(target)) deps.openUrl?.(target);
|
|
1623
|
+
else warn(`A checklist task opens "${target}": pass onNavigate to MRRocketProvider to open screens and paths.`);
|
|
1624
|
+
},
|
|
1625
|
+
task: (taskId, item) => options.onTask?.(taskId, item)
|
|
1376
1626
|
});
|
|
1377
1627
|
const refreshFlows = () => {
|
|
1378
1628
|
if (!isReady || closed) return;
|
|
@@ -2010,30 +2260,216 @@ var activeRouteName = (state) => {
|
|
|
2010
2260
|
};
|
|
2011
2261
|
|
|
2012
2262
|
// src/native/flows-view.ts
|
|
2013
|
-
var
|
|
2263
|
+
var import_react2 = require("react");
|
|
2264
|
+
|
|
2265
|
+
// src/icons.ts
|
|
2266
|
+
var FLOW_ICONS = {
|
|
2267
|
+
check: { label: "Check", paths: ["M5 12.5l4.5 4.5L19 7.5"], emoji: "\u2705" },
|
|
2268
|
+
star: { label: "Star", paths: ["M12 3.5l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.9l-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z"], emoji: "\u2B50" },
|
|
2269
|
+
rocket: {
|
|
2270
|
+
label: "Rocket",
|
|
2271
|
+
paths: ["M12 3c3 2 4.5 5.5 4 10l-2 3h-4l-2-3c-.5-4.5 1-8 4-10z", "M8 13.5l-3 3 3.5.5", "M16 13.5l3 3-3.5.5", "M13.5 9.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z", "M11 19.5v1.5M13 19.5v1.5"],
|
|
2272
|
+
emoji: "\u{1F680}"
|
|
2273
|
+
},
|
|
2274
|
+
user: { label: "Person", paths: ["M15.5 8a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z", "M5 20c.8-3.5 3.6-5.5 7-5.5s6.2 2 7 5.5"], emoji: "\u{1F464}" },
|
|
2275
|
+
users: {
|
|
2276
|
+
label: "Team",
|
|
2277
|
+
paths: ["M13 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z", "M3.5 19c.6-3 3-4.8 6.5-4.8s5.9 1.8 6.5 4.8", "M16 5.2a3 3 0 0 1 0 5.6", "M18 14.6c1.5.6 2.4 2 2.7 4.4"],
|
|
2278
|
+
emoji: "\u{1F465}"
|
|
2279
|
+
},
|
|
2280
|
+
settings: {
|
|
2281
|
+
label: "Settings",
|
|
2282
|
+
paths: ["M12 2.8v2.4M12 18.8v2.4M2.8 12h2.4M18.8 12h2.4M5.5 5.5l1.7 1.7M16.8 16.8l1.7 1.7M5.5 18.5l1.7-1.7M16.8 7.2l1.7-1.7", "M17 12a5 5 0 1 1-10 0 5 5 0 0 1 10 0z", "M14 12a2 2 0 1 1-4 0 2 2 0 0 1 4 0z"],
|
|
2283
|
+
emoji: "\u2699\uFE0F"
|
|
2284
|
+
},
|
|
2285
|
+
bell: { label: "Bell", paths: ["M6 16v-5a6 6 0 0 1 12 0v5l1.5 2h-15z", "M10 20.5a2 2 0 0 0 4 0"], emoji: "\u{1F514}" },
|
|
2286
|
+
mail: { label: "Mail", paths: ["M4 6h16v12H4z", "M4 7l8 6 8-6"], emoji: "\u2709\uFE0F" },
|
|
2287
|
+
chat: { label: "Chat", paths: ["M4 5h16v11H9l-5 4z"], emoji: "\u{1F4AC}" },
|
|
2288
|
+
heart: { label: "Heart", paths: ["M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10z"], emoji: "\u2764\uFE0F" },
|
|
2289
|
+
flag: { label: "Flag", paths: ["M5 21V4", "M5 4h11l-2 4 2 4H5"], emoji: "\u{1F6A9}" },
|
|
2290
|
+
bolt: { label: "Bolt", paths: ["M13 3L5 13.5h6L10 21l8-10.5h-6z"], emoji: "\u26A1" },
|
|
2291
|
+
book: { label: "Book", paths: ["M4 5.5C6.5 4 9.5 4 12 6c2.5-2 5.5-2 8-.5V19c-2.5-1.5-5.5-1.5-8 .5-2.5-2-5.5-2-8-.5z", "M12 6v13.5"], emoji: "\u{1F4D6}" },
|
|
2292
|
+
calendar: { label: "Calendar", paths: ["M4 6h16v14H4z", "M4 10h16", "M8 3.5v4M16 3.5v4"], emoji: "\u{1F4C5}" },
|
|
2293
|
+
camera: { label: "Camera", paths: ["M4 8h3.5L9 5.5h6L16.5 8H20v11H4z", "M15.5 13a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z"], emoji: "\u{1F4F7}" },
|
|
2294
|
+
cart: { label: "Cart", paths: ["M3.5 4.5H6l2 10h10l2-7H7", "M9.5 19.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z", "M18.5 19.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"], emoji: "\u{1F6D2}" },
|
|
2295
|
+
chart: { label: "Chart", paths: ["M4 20h16", "M7 16v-4M12 16V8M17 16V9"], emoji: "\u{1F4CA}" },
|
|
2296
|
+
gift: { label: "Gift", paths: ["M4 10h16v10H4z", "M3 7h18v3H3z", "M12 7v13", "M12 7c-1.5-3-5-3-5-1s3.5 1 5 1z", "M12 7c1.5-3 5-3 5-1s-3.5 1-5 1z"], emoji: "\u{1F381}" },
|
|
2297
|
+
home: { label: "Home", paths: ["M4 11l8-7 8 7", "M6 9.5V20h12V9.5", "M10 20v-6h4v6"], emoji: "\u{1F3E0}" },
|
|
2298
|
+
link: { label: "Link", paths: ["M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1", "M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1"], emoji: "\u{1F517}" },
|
|
2299
|
+
lock: { label: "Lock", paths: ["M6 11h12v9H6z", "M8.5 11V8a3.5 3.5 0 0 1 7 0v3"], emoji: "\u{1F512}" },
|
|
2300
|
+
pencil: { label: "Pencil", paths: ["M4 20l1-4L16 5l3 3L8 19z", "M14 7l3 3"], emoji: "\u270F\uFE0F" },
|
|
2301
|
+
plus: { label: "Plus", paths: ["M12 5v14M5 12h14"], emoji: "\u2795" },
|
|
2302
|
+
search: { label: "Search", paths: ["M16 10.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z", "M14.5 14.5L20 20"], emoji: "\u{1F50D}" },
|
|
2303
|
+
upload: { label: "Upload", paths: ["M12 15V4", "M7.5 8.5L12 4l4.5 4.5", "M4 15v5h16v-5"], emoji: "\u2B06\uFE0F" },
|
|
2304
|
+
play: { label: "Play", paths: ["M8 5l11 7-11 7z"], emoji: "\u25B6\uFE0F" },
|
|
2305
|
+
sparkle: { label: "Sparkle", paths: ["M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z", "M19 16l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7z"], emoji: "\u2728" },
|
|
2306
|
+
globe: {
|
|
2307
|
+
label: "Globe",
|
|
2308
|
+
paths: ["M20 12a8 8 0 1 1-16 0 8 8 0 0 1 16 0z", "M4 12h16", "M12 4c2.2 2.2 3.3 4.9 3.3 8s-1.1 5.8-3.3 8c-2.2-2.2-3.3-4.9-3.3-8S9.8 6.2 12 4z"],
|
|
2309
|
+
emoji: "\u{1F310}"
|
|
2310
|
+
}
|
|
2311
|
+
};
|
|
2312
|
+
var FLOW_ICON_NAMES = Object.keys(FLOW_ICONS);
|
|
2313
|
+
var iconOf = (icon) => {
|
|
2314
|
+
if (!icon) return void 0;
|
|
2315
|
+
if (icon.kind === "builtin") return icon.name && FLOW_ICONS[icon.name] ? icon : void 0;
|
|
2316
|
+
if (icon.kind === "emoji") return icon.value && icon.value.trim() && [...icon.value.trim()].length <= 8 ? icon : void 0;
|
|
2317
|
+
if (icon.kind === "image") return icon.url && /^https?:\/\//i.test(icon.url) ? icon : void 0;
|
|
2318
|
+
return void 0;
|
|
2319
|
+
};
|
|
2320
|
+
|
|
2321
|
+
// src/native/flows-view.ts
|
|
2014
2322
|
var RN = require("react-native");
|
|
2323
|
+
var svg = (() => {
|
|
2324
|
+
try {
|
|
2325
|
+
return require("react-native-svg");
|
|
2326
|
+
} catch {
|
|
2327
|
+
return null;
|
|
2328
|
+
}
|
|
2329
|
+
})();
|
|
2330
|
+
var iconNode = (icon, size, color) => {
|
|
2331
|
+
const i = iconOf(icon);
|
|
2332
|
+
if (!i) return null;
|
|
2333
|
+
if (i.kind === "image")
|
|
2334
|
+
return RN.Image ? (0, import_react2.createElement)(RN.Image, { source: { uri: i.url }, accessibilityElementsHidden: true, style: { width: size, height: size, borderRadius: size / 4 } }) : null;
|
|
2335
|
+
const Svg = svg?.Svg ?? svg?.default;
|
|
2336
|
+
if (i.kind === "builtin" && Svg && svg?.Path)
|
|
2337
|
+
return (0, import_react2.createElement)(
|
|
2338
|
+
Svg,
|
|
2339
|
+
{ width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" },
|
|
2340
|
+
...FLOW_ICONS[i.name].paths.map((d, k) => (0, import_react2.createElement)(svg.Path, { key: k, d }))
|
|
2341
|
+
);
|
|
2342
|
+
return (0, import_react2.createElement)(RN.Text, { style: { fontSize: size * 0.8, lineHeight: size, textAlign: "center", width: size } }, i.kind === "emoji" ? i.value : FLOW_ICONS[i.name].emoji);
|
|
2343
|
+
};
|
|
2344
|
+
var FINALE_COLORS = ["#f59e0b", "#10b981", "#ef4444", "#8b5cf6", "#06b6d4", "#ec4899"];
|
|
2345
|
+
var finaleBits = (kind, accent) => {
|
|
2346
|
+
const rnd = (a, b) => a + Math.random() * (b - a);
|
|
2347
|
+
const colors = [accent, accent, ...FINALE_COLORS];
|
|
2348
|
+
const pick = () => colors[Math.floor(Math.random() * colors.length)];
|
|
2349
|
+
if (kind === "confetti")
|
|
2350
|
+
return Array.from({ length: 48 }, (_, i) => ({
|
|
2351
|
+
x: i % 2 ? 12 : 82,
|
|
2352
|
+
y: 92,
|
|
2353
|
+
dx: (i % 2 ? 1 : -1) * rnd(40, 200),
|
|
2354
|
+
mid: -rnd(380, 620),
|
|
2355
|
+
dy: -rnd(120, 300),
|
|
2356
|
+
size: rnd(7, 11),
|
|
2357
|
+
rot: rnd(-540, 540),
|
|
2358
|
+
color: pick(),
|
|
2359
|
+
delay: rnd(0, 160),
|
|
2360
|
+
life: rnd(1500, 2e3),
|
|
2361
|
+
shape: "rect"
|
|
2362
|
+
}));
|
|
2363
|
+
if (kind === "fireworks")
|
|
2364
|
+
return Array.from({ length: 3 }, (_, b) => {
|
|
2365
|
+
const x = rnd(20, 75);
|
|
2366
|
+
const y = rnd(18, 45);
|
|
2367
|
+
const color = pick();
|
|
2368
|
+
return Array.from({ length: 18 }, (_2, i) => {
|
|
2369
|
+
const a = Math.PI * 2 * i / 18;
|
|
2370
|
+
const r = rnd(70, 130);
|
|
2371
|
+
return { x, y, dx: Math.cos(a) * r, mid: Math.sin(a) * r * 0.8, dy: Math.sin(a) * r + 40, size: 5, rot: 0, color, delay: b * 320, life: rnd(900, 1200), shape: "dot" };
|
|
2372
|
+
});
|
|
2373
|
+
}).flat();
|
|
2374
|
+
return Array.from({ length: 22 }, () => ({
|
|
2375
|
+
x: rnd(6, 88),
|
|
2376
|
+
y: rnd(20, 80),
|
|
2377
|
+
dx: 0,
|
|
2378
|
+
mid: -rnd(10, 25),
|
|
2379
|
+
dy: -rnd(30, 60),
|
|
2380
|
+
size: rnd(16, 28),
|
|
2381
|
+
rot: rnd(-40, 40),
|
|
2382
|
+
color: pick(),
|
|
2383
|
+
delay: rnd(0, 600),
|
|
2384
|
+
life: rnd(900, 1300),
|
|
2385
|
+
shape: "star"
|
|
2386
|
+
}));
|
|
2387
|
+
};
|
|
2388
|
+
var Finale = ({ kind, accent }) => {
|
|
2389
|
+
const A = RN.Animated;
|
|
2390
|
+
const [bits] = (0, import_react2.useState)(() => finaleBits(kind, accent));
|
|
2391
|
+
const [values] = (0, import_react2.useState)(() => A ? bits.map(() => new A.Value(0)) : []);
|
|
2392
|
+
const [on, setOn] = (0, import_react2.useState)(!!A);
|
|
2393
|
+
(0, import_react2.useEffect)(() => {
|
|
2394
|
+
if (!A) return;
|
|
2395
|
+
let stopped = false;
|
|
2396
|
+
let run = null;
|
|
2397
|
+
const go = () => {
|
|
2398
|
+
if (stopped) return;
|
|
2399
|
+
run = A.parallel(values.map((v, i) => A.timing(v, { toValue: 1, duration: bits[i].life, delay: bits[i].delay, useNativeDriver: true })));
|
|
2400
|
+
run.start(() => !stopped && setOn(false));
|
|
2401
|
+
};
|
|
2402
|
+
Promise.resolve(RN.AccessibilityInfo?.isReduceMotionEnabled?.()).then((reduce) => reduce ? !stopped && setOn(false) : go()).catch(go);
|
|
2403
|
+
return () => {
|
|
2404
|
+
stopped = true;
|
|
2405
|
+
run?.stop();
|
|
2406
|
+
};
|
|
2407
|
+
}, [A, bits, values]);
|
|
2408
|
+
if (!on || !A) return null;
|
|
2409
|
+
return (0, import_react2.createElement)(
|
|
2410
|
+
RN.View,
|
|
2411
|
+
{ pointerEvents: "none", accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: { position: "absolute", left: 0, right: 0, top: 0, bottom: 0 } },
|
|
2412
|
+
...bits.map((b, i) => {
|
|
2413
|
+
const t = values[i];
|
|
2414
|
+
const fade = t.interpolate({ inputRange: [0, 0.7, 1], outputRange: [1, 1, 0] });
|
|
2415
|
+
const scale = b.shape === "star" ? t.interpolate({ inputRange: [0, 0.25, 1], outputRange: [0.2, 1.15, 0.6] }) : 1;
|
|
2416
|
+
return (0, import_react2.createElement)(
|
|
2417
|
+
A.View,
|
|
2418
|
+
{
|
|
2419
|
+
key: i,
|
|
2420
|
+
style: {
|
|
2421
|
+
position: "absolute",
|
|
2422
|
+
left: `${b.x}%`,
|
|
2423
|
+
top: `${b.y}%`,
|
|
2424
|
+
width: b.size,
|
|
2425
|
+
height: b.shape === "rect" ? b.size * 0.45 : b.size,
|
|
2426
|
+
borderRadius: b.shape === "dot" ? b.size / 2 : 2,
|
|
2427
|
+
backgroundColor: b.shape === "star" ? "transparent" : b.color,
|
|
2428
|
+
alignItems: "center",
|
|
2429
|
+
justifyContent: "center",
|
|
2430
|
+
opacity: fade,
|
|
2431
|
+
transform: [
|
|
2432
|
+
{ translateX: t.interpolate({ inputRange: [0, 1], outputRange: [0, b.dx] }) },
|
|
2433
|
+
{ translateY: t.interpolate({ inputRange: [0, 0.5, 1], outputRange: [0, b.mid, b.dy] }) },
|
|
2434
|
+
{ rotate: t.interpolate({ inputRange: [0, 1], outputRange: ["0deg", `${b.rot}deg`] }) },
|
|
2435
|
+
{ scale }
|
|
2436
|
+
]
|
|
2437
|
+
}
|
|
2438
|
+
},
|
|
2439
|
+
b.shape === "star" ? (0, import_react2.createElement)(RN.Text, { style: { color: b.color, fontSize: b.size, lineHeight: b.size } }, "\u2605") : null
|
|
2440
|
+
);
|
|
2441
|
+
})
|
|
2442
|
+
);
|
|
2443
|
+
};
|
|
2015
2444
|
var LIGHT = { bg: "#ffffff", fg: "#1c1d20", muted: "#5d6068", soft: "#f4f5f7", line: "#e4e5e8" };
|
|
2016
2445
|
var DARK = { bg: "#17181b", fg: "#f1f2f4", muted: "#a9acb3", soft: "#232428", line: "#2e2f35" };
|
|
2017
2446
|
var months = (n) => `${n} ${n === 1 ? "month" : "months"}`;
|
|
2018
|
-
var MRRocketFlows = (
|
|
2447
|
+
var MRRocketFlows = (props) => {
|
|
2448
|
+
const [, setTick] = (0, import_react2.useState)(0);
|
|
2449
|
+
(0, import_react2.useEffect)(() => props.flows.subscribe(() => setTick((t) => t + 1)), [props.flows]);
|
|
2450
|
+
const fin = props.flows.finale?.() ?? null;
|
|
2451
|
+
const accent = props.appearance?.accent ?? props.flows.accent?.() ?? "#3f76ff";
|
|
2452
|
+
return (0, import_react2.createElement)(import_react2.Fragment, null, (0, import_react2.createElement)(FlowsBody, props), fin ? (0, import_react2.createElement)(Finale, { key: fin.key, kind: fin.kind, accent }) : null);
|
|
2453
|
+
};
|
|
2454
|
+
var FlowsBody = ({ flows, paywall, appearance = {} }) => {
|
|
2019
2455
|
const scheme = RN.useColorScheme?.();
|
|
2020
2456
|
const dark = appearance.theme === "dark" || (appearance.theme ?? "auto") === "auto" && scheme === "dark";
|
|
2021
|
-
const p = { ...dark ? DARK : LIGHT, accent: appearance.accent ?? "#3f76ff", danger: "#d92d20" };
|
|
2022
|
-
const [, setTick] = (0,
|
|
2023
|
-
(0,
|
|
2024
|
-
(0,
|
|
2457
|
+
const p = { ...dark ? DARK : LIGHT, accent: appearance.accent ?? flows.accent?.() ?? "#3f76ff", danger: "#d92d20" };
|
|
2458
|
+
const [, setTick] = (0, import_react2.useState)(0);
|
|
2459
|
+
(0, import_react2.useEffect)(() => flows.subscribe(() => setTick((t) => t + 1)), [flows]);
|
|
2460
|
+
(0, import_react2.useEffect)(() => paywall?.subscribe(() => setTick((t) => t + 1)), [paywall]);
|
|
2025
2461
|
const pw = paywall?.view() ?? null;
|
|
2026
2462
|
const v = flows.view();
|
|
2027
|
-
const [comment, setComment] = (0,
|
|
2463
|
+
const [comment, setComment] = (0, import_react2.useState)("");
|
|
2028
2464
|
const screen = v?.type === "cancel" ? v.screen : null;
|
|
2029
|
-
(0,
|
|
2465
|
+
(0, import_react2.useEffect)(() => {
|
|
2030
2466
|
if (!screen) setComment("");
|
|
2031
2467
|
}, [screen]);
|
|
2032
2468
|
if (!v && !pw) return null;
|
|
2033
|
-
const text2 = (children, style = {}) => (0,
|
|
2469
|
+
const text2 = (children, style = {}) => (0, import_react2.createElement)(RN.Text, { style: { color: p.fg, fontSize: 15, ...style } }, children);
|
|
2034
2470
|
const muted = (children, style = {}) => text2(children, { color: p.muted, fontSize: 13, ...style });
|
|
2035
|
-
const title = (children) => (0,
|
|
2036
|
-
const btn = (label, kind, onPress, disabled = false) => (0,
|
|
2471
|
+
const title = (children) => (0, import_react2.createElement)(RN.Text, { accessibilityRole: "header", style: { color: p.fg, fontSize: 18, fontWeight: "700" } }, children);
|
|
2472
|
+
const btn = (label, kind, onPress, disabled = false) => (0, import_react2.createElement)(
|
|
2037
2473
|
RN.Pressable,
|
|
2038
2474
|
{
|
|
2039
2475
|
key: label,
|
|
@@ -2057,12 +2493,12 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2057
2493
|
fontWeight: kind === "quiet" ? "500" : "600"
|
|
2058
2494
|
})
|
|
2059
2495
|
);
|
|
2060
|
-
const close = (label, onPress) => (0,
|
|
2496
|
+
const close = (label, onPress) => (0, import_react2.createElement)(
|
|
2061
2497
|
RN.Pressable,
|
|
2062
2498
|
{ onPress, accessibilityRole: "button", accessibilityLabel: label, hitSlop: 12, style: { marginLeft: "auto", padding: 4 } },
|
|
2063
2499
|
text2("\xD7", { fontSize: 22, color: p.muted })
|
|
2064
2500
|
);
|
|
2065
|
-
const card = (children, style = {}) => (0,
|
|
2501
|
+
const card = (children, style = {}) => (0, import_react2.createElement)(
|
|
2066
2502
|
RN.View,
|
|
2067
2503
|
{
|
|
2068
2504
|
style: {
|
|
@@ -2079,16 +2515,16 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2079
2515
|
},
|
|
2080
2516
|
...children
|
|
2081
2517
|
);
|
|
2082
|
-
const sheet = (children, onClose) => (0,
|
|
2518
|
+
const sheet = (children, onClose) => (0, import_react2.createElement)(
|
|
2083
2519
|
RN.Modal,
|
|
2084
2520
|
{ visible: true, transparent: true, animationType: "fade", onRequestClose: onClose },
|
|
2085
|
-
(0,
|
|
2521
|
+
(0, import_react2.createElement)(
|
|
2086
2522
|
RN.View,
|
|
2087
2523
|
{ style: { flex: 1, backgroundColor: "rgba(0,0,0,0.4)", justifyContent: "flex-end" } },
|
|
2088
2524
|
card(children, { borderBottomLeftRadius: 0, borderBottomRightRadius: 0, paddingBottom: 34 })
|
|
2089
2525
|
)
|
|
2090
2526
|
);
|
|
2091
|
-
const input = (placeholder, value = comment, onChange = setComment) => (0,
|
|
2527
|
+
const input = (placeholder, value = comment, onChange = setComment) => (0, import_react2.createElement)(RN.TextInput, {
|
|
2092
2528
|
value,
|
|
2093
2529
|
onChangeText: onChange,
|
|
2094
2530
|
placeholder,
|
|
@@ -2103,19 +2539,19 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2103
2539
|
const host = paywall;
|
|
2104
2540
|
return sheet(
|
|
2105
2541
|
[
|
|
2106
|
-
(0,
|
|
2542
|
+
(0, import_react2.createElement)(
|
|
2107
2543
|
RN.View,
|
|
2108
2544
|
{ key: "top", style: { flexDirection: "row", alignItems: "center", gap: 4 } },
|
|
2109
2545
|
...w.total > 1 ? Array.from(
|
|
2110
2546
|
{ length: w.total },
|
|
2111
|
-
(_, i) => (0,
|
|
2547
|
+
(_, i) => (0, import_react2.createElement)(RN.View, { key: i, style: { width: 16, height: 4, borderRadius: 4, backgroundColor: i <= w.index ? p.accent : p.line } })
|
|
2112
2548
|
) : [],
|
|
2113
2549
|
close("Close", host.close)
|
|
2114
2550
|
),
|
|
2115
2551
|
title(pg.title),
|
|
2116
2552
|
pg.body ? muted(pg.body, { fontSize: 15 }) : null,
|
|
2117
2553
|
...pg.kind === "benefits" ? (pg.items ?? []).map(
|
|
2118
|
-
(item, i) => (0,
|
|
2554
|
+
(item, i) => (0, import_react2.createElement)(
|
|
2119
2555
|
RN.View,
|
|
2120
2556
|
{ key: `b${i}`, style: { flexDirection: "row", gap: 10, alignItems: "flex-start" } },
|
|
2121
2557
|
text2("\u2713", { color: p.accent, fontWeight: "700" }),
|
|
@@ -2123,13 +2559,13 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2123
2559
|
)
|
|
2124
2560
|
) : [],
|
|
2125
2561
|
...pg.kind === "proof" ? (pg.quotes ?? []).map(
|
|
2126
|
-
(q, i) => (0,
|
|
2562
|
+
(q, i) => (0, import_react2.createElement)(RN.View, { key: `q${i}`, style: { backgroundColor: p.soft, borderRadius: 12, padding: 12, gap: 6 } }, text2(q.text), q.by ? muted(q.by) : null)
|
|
2127
2563
|
) : [],
|
|
2128
|
-
pg.kind === "plans" ? (0,
|
|
2564
|
+
pg.kind === "plans" ? (0, import_react2.createElement)(
|
|
2129
2565
|
RN.View,
|
|
2130
2566
|
{ key: "plans", accessibilityRole: "radiogroup", style: { gap: 6 } },
|
|
2131
2567
|
...w.plans.map(
|
|
2132
|
-
(plan) => (0,
|
|
2568
|
+
(plan) => (0, import_react2.createElement)(
|
|
2133
2569
|
RN.Pressable,
|
|
2134
2570
|
{
|
|
2135
2571
|
key: plan.id,
|
|
@@ -2149,7 +2585,7 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2149
2585
|
gap: 10
|
|
2150
2586
|
}
|
|
2151
2587
|
},
|
|
2152
|
-
(0,
|
|
2588
|
+
(0, import_react2.createElement)(RN.View, { style: { flex: 1 } }, text2(plan.name, { fontWeight: "600" }), plan.note ? muted(plan.note) : null),
|
|
2153
2589
|
text2(plan.price, { fontWeight: "700" })
|
|
2154
2590
|
)
|
|
2155
2591
|
)
|
|
@@ -2164,22 +2600,22 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2164
2600
|
if (pw) return paywallSheet(pw);
|
|
2165
2601
|
if (!v) return null;
|
|
2166
2602
|
if (v.type === "cancel") {
|
|
2167
|
-
const top = (0,
|
|
2603
|
+
const top = (0, import_react2.createElement)(
|
|
2168
2604
|
RN.View,
|
|
2169
2605
|
{ style: { flexDirection: "row", alignItems: "center", gap: 4 } },
|
|
2170
2606
|
...v.steps > 1 ? Array.from(
|
|
2171
2607
|
{ length: v.steps },
|
|
2172
|
-
(_, i) => (0,
|
|
2608
|
+
(_, i) => (0, import_react2.createElement)(RN.View, { key: i, style: { width: 16, height: 4, borderRadius: 4, backgroundColor: i < v.step ? p.accent : p.line } })
|
|
2173
2609
|
) : [],
|
|
2174
2610
|
close("Close", flows.cancel.close)
|
|
2175
2611
|
);
|
|
2176
2612
|
const error = v.error ? text2(v.error, { color: p.danger, fontSize: 13 }) : null;
|
|
2177
2613
|
let body = [];
|
|
2178
|
-
const choices = (items) => (0,
|
|
2614
|
+
const choices = (items) => (0, import_react2.createElement)(
|
|
2179
2615
|
RN.ScrollView,
|
|
2180
2616
|
{ style: { maxHeight: 320 }, contentContainerStyle: { gap: 6 }, accessibilityRole: "radiogroup" },
|
|
2181
2617
|
...items.map(
|
|
2182
|
-
(c) => (0,
|
|
2618
|
+
(c) => (0, import_react2.createElement)(
|
|
2183
2619
|
RN.Pressable,
|
|
2184
2620
|
{
|
|
2185
2621
|
key: c.key,
|
|
@@ -2224,7 +2660,7 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2224
2660
|
body = [
|
|
2225
2661
|
label ? muted(`You said: ${label}`) : null,
|
|
2226
2662
|
title(o.headline),
|
|
2227
|
-
detail ? (0,
|
|
2663
|
+
detail ? (0, import_react2.createElement)(RN.View, { style: { backgroundColor: p.soft, borderRadius: 10, padding: 12 } }, text2(detail, { fontWeight: "600" })) : null,
|
|
2228
2664
|
o.kind === "contact" ? input("What would make you stay?") : null,
|
|
2229
2665
|
btn(v.busy ? "One moment\u2026" : offerButton(o), "primary", () => flows.cancel.accept(comment), v.busy),
|
|
2230
2666
|
btn("No thanks, continue cancelling", "quiet", flows.cancel.decline, v.busy)
|
|
@@ -2243,7 +2679,7 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2243
2679
|
const m2 = mediaOf(s);
|
|
2244
2680
|
if (!m2) return null;
|
|
2245
2681
|
if (m2.kind === "image")
|
|
2246
|
-
return RN.Image ? (0,
|
|
2682
|
+
return RN.Image ? (0, import_react2.createElement)(RN.Image, {
|
|
2247
2683
|
key: "media",
|
|
2248
2684
|
source: { uri: m2.url },
|
|
2249
2685
|
accessibilityLabel: m2.alt,
|
|
@@ -2255,15 +2691,75 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2255
2691
|
return RN.Linking ? btn("\u25B6 Watch the video", "secondary", () => void RN.Linking?.openURL(open).catch(() => {
|
|
2256
2692
|
})) : null;
|
|
2257
2693
|
};
|
|
2694
|
+
if (v.type === "step" && v.step.kind === "question") {
|
|
2695
|
+
const s = v.step;
|
|
2696
|
+
const q = s.question;
|
|
2697
|
+
const ok = answerOk(q, v.answer);
|
|
2698
|
+
return sheet(
|
|
2699
|
+
[
|
|
2700
|
+
(0, import_react2.createElement)(
|
|
2701
|
+
RN.View,
|
|
2702
|
+
{ key: "top", style: { flexDirection: "row", alignItems: "center", gap: 4 } },
|
|
2703
|
+
...v.total > 1 ? Array.from(
|
|
2704
|
+
{ length: v.total },
|
|
2705
|
+
(_, i) => (0, import_react2.createElement)(RN.View, { key: i, style: { width: 16, height: 4, borderRadius: 4, backgroundColor: i <= v.index ? p.accent : p.line } })
|
|
2706
|
+
) : [],
|
|
2707
|
+
close("Close", flows.onboarding.dismiss)
|
|
2708
|
+
),
|
|
2709
|
+
v.index === 0 && v.flow.icon ? (0, import_react2.createElement)(RN.View, { key: "icon" }, iconNode(v.flow.icon, 36, p.accent)) : null,
|
|
2710
|
+
title(s.title),
|
|
2711
|
+
s.body ? muted(s.body, { fontSize: 15 }) : null,
|
|
2712
|
+
q?.type === "choice" ? (0, import_react2.createElement)(
|
|
2713
|
+
RN.ScrollView,
|
|
2714
|
+
{ key: "opts", style: { maxHeight: 320 }, contentContainerStyle: { gap: 6 }, accessibilityRole: "radiogroup" },
|
|
2715
|
+
...(q.options ?? []).map(
|
|
2716
|
+
(o) => (0, import_react2.createElement)(
|
|
2717
|
+
RN.Pressable,
|
|
2718
|
+
{
|
|
2719
|
+
key: o.id,
|
|
2720
|
+
onPress: () => flows.onboarding.answer(o.id),
|
|
2721
|
+
accessibilityRole: "radio",
|
|
2722
|
+
accessibilityState: { checked: v.answer === o.id },
|
|
2723
|
+
style: {
|
|
2724
|
+
minHeight: 44,
|
|
2725
|
+
paddingHorizontal: 12,
|
|
2726
|
+
borderRadius: 10,
|
|
2727
|
+
borderWidth: 1,
|
|
2728
|
+
borderColor: v.answer === o.id ? p.accent : p.line,
|
|
2729
|
+
backgroundColor: v.answer === o.id ? p.soft : p.bg,
|
|
2730
|
+
justifyContent: "center"
|
|
2731
|
+
}
|
|
2732
|
+
},
|
|
2733
|
+
text2(o.label, { fontWeight: "500" })
|
|
2734
|
+
)
|
|
2735
|
+
)
|
|
2736
|
+
) : q ? (0, import_react2.createElement)(RN.TextInput, {
|
|
2737
|
+
key: "answer",
|
|
2738
|
+
value: v.answer ?? "",
|
|
2739
|
+
onChangeText: (t) => flows.onboarding.answer(t),
|
|
2740
|
+
onSubmitEditing: flows.onboarding.next,
|
|
2741
|
+
placeholder: q.placeholder || "Your answer",
|
|
2742
|
+
placeholderTextColor: p.muted,
|
|
2743
|
+
maxLength: 500,
|
|
2744
|
+
accessibilityLabel: s.title,
|
|
2745
|
+
style: { height: 44, borderWidth: 1, borderColor: p.line, borderRadius: 10, paddingHorizontal: 12, color: p.fg }
|
|
2746
|
+
}) : null,
|
|
2747
|
+
btn(s.button || (v.last ? "Done" : "Continue"), "primary", flows.onboarding.next, !ok),
|
|
2748
|
+
v.back ? btn("Back", "quiet", flows.onboarding.back) : null
|
|
2749
|
+
],
|
|
2750
|
+
flows.onboarding.dismiss
|
|
2751
|
+
);
|
|
2752
|
+
}
|
|
2258
2753
|
if (v.type === "step")
|
|
2259
2754
|
return sheet(
|
|
2260
2755
|
[
|
|
2261
|
-
(0,
|
|
2756
|
+
(0, import_react2.createElement)(
|
|
2262
2757
|
RN.View,
|
|
2263
2758
|
{ style: { flexDirection: "row", alignItems: "center" } },
|
|
2264
2759
|
v.total > 1 ? muted(`Step ${v.index + 1} of ${v.total}`) : null,
|
|
2265
2760
|
close("Close the tour", flows.onboarding.dismiss)
|
|
2266
2761
|
),
|
|
2762
|
+
v.step.kind === "modal" && v.flow.icon ? (0, import_react2.createElement)(RN.View, { key: "icon" }, iconNode(v.flow.icon, 36, p.accent)) : null,
|
|
2267
2763
|
media(v.step),
|
|
2268
2764
|
title(v.step.title),
|
|
2269
2765
|
v.step.body ? muted(v.step.body, { fontSize: 15 }) : null,
|
|
@@ -2273,11 +2769,11 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2273
2769
|
);
|
|
2274
2770
|
if (v.type === "checklist") {
|
|
2275
2771
|
const done = v.items.filter((i) => i.done).length;
|
|
2276
|
-
return (0,
|
|
2772
|
+
return (0, import_react2.createElement)(
|
|
2277
2773
|
RN.View,
|
|
2278
2774
|
{ pointerEvents: "box-none", style: { position: "absolute", left: 12, right: 12, bottom: 28 } },
|
|
2279
2775
|
card([
|
|
2280
|
-
(0,
|
|
2776
|
+
(0, import_react2.createElement)(
|
|
2281
2777
|
RN.View,
|
|
2282
2778
|
{ key: "t", style: { flexDirection: "row", alignItems: "center" } },
|
|
2283
2779
|
title(v.flow.name),
|
|
@@ -2285,18 +2781,19 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2285
2781
|
),
|
|
2286
2782
|
muted(`${done} of ${v.items.length} done`),
|
|
2287
2783
|
...v.items.map(
|
|
2288
|
-
({ step, done: d,
|
|
2784
|
+
({ step, done: d, opens }) => (0, import_react2.createElement)(
|
|
2289
2785
|
RN.Pressable,
|
|
2290
2786
|
{
|
|
2291
2787
|
key: step.id,
|
|
2292
|
-
// 0.17.0:
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2788
|
+
// 0.17.0/0.18.0: a task that opens something (a tour, a modal, a screen, the app's code) does it;
|
|
2789
|
+
// a finished tour or modal ticks it, a screen or the app's code once opened (unless an event does).
|
|
2790
|
+
disabled: d || !!step.event && !opens,
|
|
2791
|
+
onPress: () => opens ? flows.onboarding.open(step.id) : flows.onboarding.check(step.id),
|
|
2792
|
+
accessibilityRole: opens && !d ? "button" : "checkbox",
|
|
2296
2793
|
accessibilityState: { checked: d },
|
|
2297
2794
|
style: { flexDirection: "row", gap: 10, alignItems: "flex-start", paddingVertical: 6 }
|
|
2298
2795
|
},
|
|
2299
|
-
(0,
|
|
2796
|
+
(0, import_react2.createElement)(
|
|
2300
2797
|
RN.View,
|
|
2301
2798
|
{
|
|
2302
2799
|
style: {
|
|
@@ -2312,7 +2809,8 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2312
2809
|
},
|
|
2313
2810
|
d ? text2("\u2713", { color: "#fff", fontSize: 12 }) : null
|
|
2314
2811
|
),
|
|
2315
|
-
(
|
|
2812
|
+
step.icon ? iconNode(step.icon, 20, p.accent) : null,
|
|
2813
|
+
(0, import_react2.createElement)(
|
|
2316
2814
|
RN.View,
|
|
2317
2815
|
{ style: { flex: 1 } },
|
|
2318
2816
|
text2(step.title, { fontWeight: "600", color: d ? p.muted : p.fg, textDecorationLine: d ? "line-through" : "none" }),
|
|
@@ -2325,14 +2823,14 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2325
2823
|
}
|
|
2326
2824
|
const m = v.message;
|
|
2327
2825
|
if (m.style === "banner")
|
|
2328
|
-
return (0,
|
|
2826
|
+
return (0, import_react2.createElement)(
|
|
2329
2827
|
RN.View,
|
|
2330
2828
|
{ pointerEvents: "box-none", style: { position: "absolute", left: 12, right: 12, top: 56 } },
|
|
2331
2829
|
card([
|
|
2332
|
-
(0,
|
|
2830
|
+
(0, import_react2.createElement)(
|
|
2333
2831
|
RN.View,
|
|
2334
2832
|
{ key: "t", style: { flexDirection: "row", alignItems: "center", gap: 8 } },
|
|
2335
|
-
(0,
|
|
2833
|
+
(0, import_react2.createElement)(RN.View, { style: { flex: 1 } }, text2(m.title, { fontWeight: "700" }), m.body ? muted(m.body) : null),
|
|
2336
2834
|
close("Dismiss", flows.message.dismiss)
|
|
2337
2835
|
),
|
|
2338
2836
|
m.button ? btn(m.button, "primary", flows.message.click) : null
|
|
@@ -2340,7 +2838,7 @@ var MRRocketFlows = ({ flows, paywall, appearance = {} }) => {
|
|
|
2340
2838
|
);
|
|
2341
2839
|
return sheet(
|
|
2342
2840
|
[
|
|
2343
|
-
(0,
|
|
2841
|
+
(0, import_react2.createElement)(RN.View, { key: "t", style: { flexDirection: "row" } }, close("Dismiss", flows.message.dismiss)),
|
|
2344
2842
|
title(m.title),
|
|
2345
2843
|
m.body ? muted(m.body, { fontSize: 15 }) : null,
|
|
2346
2844
|
m.button ? btn(m.button, "primary", flows.message.click) : null
|
|
@@ -2523,7 +3021,7 @@ var optionalModules = () => ({
|
|
|
2523
3021
|
});
|
|
2524
3022
|
|
|
2525
3023
|
// src/native/widgets-view.ts
|
|
2526
|
-
var
|
|
3024
|
+
var import_react3 = require("react");
|
|
2527
3025
|
var RN3 = require("react-native");
|
|
2528
3026
|
var usePalette = (appearance = {}) => {
|
|
2529
3027
|
const scheme = RN3.useColorScheme?.();
|
|
@@ -2531,10 +3029,10 @@ var usePalette = (appearance = {}) => {
|
|
|
2531
3029
|
return { ...dark ? DARK : LIGHT, accent: appearance.accent ?? "#3f76ff", danger: "#d92d20" };
|
|
2532
3030
|
};
|
|
2533
3031
|
var kit = (p) => {
|
|
2534
|
-
const text2 = (children, style = {}) => (0,
|
|
3032
|
+
const text2 = (children, style = {}) => (0, import_react3.createElement)(RN3.Text, { style: { color: p.fg, fontSize: 15, ...style } }, children);
|
|
2535
3033
|
const muted = (children, style = {}) => text2(children, { color: p.muted, fontSize: 13, ...style });
|
|
2536
|
-
const title = (children) => (0,
|
|
2537
|
-
const btn = (label, kind, onPress, disabled = false, style = {}) => (0,
|
|
3034
|
+
const title = (children) => (0, import_react3.createElement)(RN3.Text, { accessibilityRole: "header", style: { color: p.fg, fontSize: 17, fontWeight: "700", flex: 1 } }, children);
|
|
3035
|
+
const btn = (label, kind, onPress, disabled = false, style = {}) => (0, import_react3.createElement)(
|
|
2538
3036
|
RN3.Pressable,
|
|
2539
3037
|
{
|
|
2540
3038
|
key: label,
|
|
@@ -2557,8 +3055,8 @@ var kit = (p) => {
|
|
|
2557
3055
|
},
|
|
2558
3056
|
text2(label, { color: kind === "primary" ? "#ffffff" : p.fg, fontWeight: "600" })
|
|
2559
3057
|
);
|
|
2560
|
-
const closeX = (label, onPress) => (0,
|
|
2561
|
-
const field = (o) => (0,
|
|
3058
|
+
const closeX = (label, onPress) => (0, import_react3.createElement)(RN3.Pressable, { onPress, accessibilityRole: "button", accessibilityLabel: label, hitSlop: 12, style: { padding: 4 } }, text2("\xD7", { fontSize: 24, color: p.muted }));
|
|
3059
|
+
const field = (o) => (0, import_react3.createElement)(RN3.TextInput, {
|
|
2562
3060
|
value: o.value,
|
|
2563
3061
|
onChangeText: o.onChange,
|
|
2564
3062
|
placeholder: o.placeholder,
|
|
@@ -2581,7 +3079,7 @@ var kit = (p) => {
|
|
|
2581
3079
|
...o.style
|
|
2582
3080
|
}
|
|
2583
3081
|
});
|
|
2584
|
-
const chip = (label, on, onPress, key = label) => (0,
|
|
3082
|
+
const chip = (label, on, onPress, key = label) => (0, import_react3.createElement)(
|
|
2585
3083
|
RN3.Pressable,
|
|
2586
3084
|
{
|
|
2587
3085
|
key,
|
|
@@ -2592,13 +3090,13 @@ var kit = (p) => {
|
|
|
2592
3090
|
},
|
|
2593
3091
|
text2(label, { fontSize: 13, fontWeight: "600", color: on ? p.accent : p.fg })
|
|
2594
3092
|
);
|
|
2595
|
-
const page = (heading, onClose, children) => (0,
|
|
3093
|
+
const page = (heading, onClose, children) => (0, import_react3.createElement)(
|
|
2596
3094
|
RN3.Modal,
|
|
2597
3095
|
{ visible: true, animationType: "slide", presentationStyle: "pageSheet", onRequestClose: onClose },
|
|
2598
|
-
(0,
|
|
3096
|
+
(0, import_react3.createElement)(
|
|
2599
3097
|
RN3.KeyboardAvoidingView,
|
|
2600
3098
|
{ behavior: RN3.Platform.OS === "ios" ? "padding" : void 0, style: { flex: 1, backgroundColor: p.bg } },
|
|
2601
|
-
(0,
|
|
3099
|
+
(0, import_react3.createElement)(
|
|
2602
3100
|
RN3.View,
|
|
2603
3101
|
{ style: { flexDirection: "row", alignItems: "center", paddingHorizontal: 16, paddingTop: 16, paddingBottom: 12, borderBottomWidth: 1, borderBottomColor: p.line } },
|
|
2604
3102
|
title(heading),
|
|
@@ -2626,8 +3124,8 @@ var opener = () => {
|
|
|
2626
3124
|
listeners.forEach((l) => l(v));
|
|
2627
3125
|
};
|
|
2628
3126
|
const useOpen = () => {
|
|
2629
|
-
const [v, setV] = (0,
|
|
2630
|
-
(0,
|
|
3127
|
+
const [v, setV] = (0, import_react3.useState)(open);
|
|
3128
|
+
(0, import_react3.useEffect)(() => {
|
|
2631
3129
|
listeners.add(setV);
|
|
2632
3130
|
setV(open);
|
|
2633
3131
|
return () => {
|
|
@@ -2641,19 +3139,19 @@ var opener = () => {
|
|
|
2641
3139
|
var isAnswered = (a) => Array.isArray(a) ? a.length > 0 : typeof a === "number" ? true : !!a?.trim();
|
|
2642
3140
|
var SurveySheet = ({ survey, api, p, onDone }) => {
|
|
2643
3141
|
const k = kit(p);
|
|
2644
|
-
const [step, setStep] = (0,
|
|
2645
|
-
const [answers, setAnswers] = (0,
|
|
2646
|
-
const [done, setDone] = (0,
|
|
2647
|
-
const [error, setError] = (0,
|
|
2648
|
-
const started = (0,
|
|
2649
|
-
const finished = (0,
|
|
3142
|
+
const [step, setStep] = (0, import_react3.useState)(0);
|
|
3143
|
+
const [answers, setAnswers] = (0, import_react3.useState)({});
|
|
3144
|
+
const [done, setDone] = (0, import_react3.useState)(false);
|
|
3145
|
+
const [error, setError] = (0, import_react3.useState)("");
|
|
3146
|
+
const started = (0, import_react3.useRef)(Date.now());
|
|
3147
|
+
const finished = (0, import_react3.useRef)(false);
|
|
2650
3148
|
const q = survey.questions[step];
|
|
2651
3149
|
const last = step === survey.questions.length - 1;
|
|
2652
3150
|
const value = answers[q.key];
|
|
2653
|
-
(0,
|
|
3151
|
+
(0, import_react3.useEffect)(() => {
|
|
2654
3152
|
api.seen(survey.id).catch(() => void 0);
|
|
2655
3153
|
}, [api, survey.id]);
|
|
2656
|
-
(0,
|
|
3154
|
+
(0, import_react3.useEffect)(() => {
|
|
2657
3155
|
if (!done) return;
|
|
2658
3156
|
const t = setTimeout(onDone, 2500);
|
|
2659
3157
|
return () => clearTimeout(t);
|
|
@@ -2682,16 +3180,16 @@ var SurveySheet = ({ survey, api, p, onDone }) => {
|
|
|
2682
3180
|
if (q.kind === "nps" || q.kind === "rating") {
|
|
2683
3181
|
const scale = q.kind === "nps" ? 11 : Math.min(Math.max(q.scale ?? 5, 2), 10);
|
|
2684
3182
|
const start = q.kind === "nps" ? 0 : 1;
|
|
2685
|
-
input = (0,
|
|
3183
|
+
input = (0, import_react3.createElement)(
|
|
2686
3184
|
RN3.View,
|
|
2687
3185
|
{ style: { gap: 6 } },
|
|
2688
|
-
(0,
|
|
3186
|
+
(0, import_react3.createElement)(
|
|
2689
3187
|
RN3.View,
|
|
2690
3188
|
{ style: { flexDirection: "row", flexWrap: "wrap", gap: 6 }, accessibilityRole: "radiogroup", accessibilityLabel: q.title },
|
|
2691
3189
|
...Array.from({ length: scale }, (_, i) => {
|
|
2692
3190
|
const n = i + start;
|
|
2693
3191
|
const on = value === n;
|
|
2694
|
-
return (0,
|
|
3192
|
+
return (0, import_react3.createElement)(
|
|
2695
3193
|
RN3.Pressable,
|
|
2696
3194
|
{
|
|
2697
3195
|
key: n,
|
|
@@ -2705,17 +3203,17 @@ var SurveySheet = ({ survey, api, p, onDone }) => {
|
|
|
2705
3203
|
);
|
|
2706
3204
|
})
|
|
2707
3205
|
),
|
|
2708
|
-
q.low || q.high || q.kind === "nps" ? (0,
|
|
3206
|
+
q.low || q.high || q.kind === "nps" ? (0, import_react3.createElement)(RN3.View, { style: { flexDirection: "row", justifyContent: "space-between" } }, k.muted(q.low ?? (q.kind === "nps" ? "Not likely" : "")), k.muted(q.high ?? (q.kind === "nps" ? "Very likely" : ""))) : null
|
|
2709
3207
|
);
|
|
2710
3208
|
} else if (q.kind === "single" || q.kind === "multi") {
|
|
2711
3209
|
const multi = q.kind === "multi";
|
|
2712
3210
|
const picked = multi ? value ?? [] : [];
|
|
2713
|
-
input = (0,
|
|
3211
|
+
input = (0, import_react3.createElement)(
|
|
2714
3212
|
RN3.View,
|
|
2715
3213
|
{ style: { gap: 6 } },
|
|
2716
3214
|
...(q.options ?? []).map((o) => {
|
|
2717
3215
|
const on = multi ? picked.includes(o) : value === o;
|
|
2718
|
-
return (0,
|
|
3216
|
+
return (0, import_react3.createElement)(
|
|
2719
3217
|
RN3.Pressable,
|
|
2720
3218
|
{
|
|
2721
3219
|
key: o,
|
|
@@ -2730,26 +3228,26 @@ var SurveySheet = ({ survey, api, p, onDone }) => {
|
|
|
2730
3228
|
);
|
|
2731
3229
|
} else input = k.field({ value: value ?? "", onChange: pick, placeholder: q.placeholder ?? "Type your answer", multiline: true });
|
|
2732
3230
|
const body = done ? [k.text(survey.thanks || "Thanks for your feedback.", { fontWeight: "600", textAlign: "center", paddingVertical: 16 })] : [
|
|
2733
|
-
(0,
|
|
3231
|
+
(0, import_react3.createElement)(
|
|
2734
3232
|
RN3.View,
|
|
2735
3233
|
{ key: "top", style: { flexDirection: "row", alignItems: "center", gap: 4 } },
|
|
2736
|
-
...survey.questions.map((x, i) => (0,
|
|
2737
|
-
(0,
|
|
3234
|
+
...survey.questions.map((x, i) => (0, import_react3.createElement)(RN3.View, { key: x.key, style: { width: 16, height: 4, borderRadius: 4, backgroundColor: i <= step ? p.accent : p.line } })),
|
|
3235
|
+
(0, import_react3.createElement)(RN3.View, { style: { flex: 1 } }),
|
|
2738
3236
|
k.closeX("Close survey", dismiss)
|
|
2739
3237
|
),
|
|
2740
|
-
(0,
|
|
3238
|
+
(0, import_react3.createElement)(RN3.Text, { key: "q", accessibilityRole: "header", style: { color: p.fg, fontSize: 17, fontWeight: "700" } }, q.title, q.required ? "" : (0, import_react3.createElement)(RN3.Text, { style: { color: p.muted, fontSize: 13, fontWeight: "400" } }, " optional")),
|
|
2741
3239
|
q.description ? k.muted(q.description) : null,
|
|
2742
3240
|
input,
|
|
2743
3241
|
error ? k.text(error, { color: p.danger, fontSize: 13 }) : null,
|
|
2744
3242
|
k.btn(last ? "Send" : "Next", "primary", next)
|
|
2745
3243
|
];
|
|
2746
|
-
return (0,
|
|
3244
|
+
return (0, import_react3.createElement)(
|
|
2747
3245
|
RN3.Modal,
|
|
2748
3246
|
{ visible: true, transparent: true, animationType: "slide", onRequestClose: dismiss },
|
|
2749
|
-
(0,
|
|
3247
|
+
(0, import_react3.createElement)(
|
|
2750
3248
|
RN3.KeyboardAvoidingView,
|
|
2751
3249
|
{ behavior: RN3.Platform.OS === "ios" ? "padding" : void 0, style: { flex: 1, backgroundColor: "rgba(0,0,0,0.35)", justifyContent: "flex-end" } },
|
|
2752
|
-
(0,
|
|
3250
|
+
(0, import_react3.createElement)(
|
|
2753
3251
|
RN3.View,
|
|
2754
3252
|
{
|
|
2755
3253
|
accessibilityViewIsModal: true,
|
|
@@ -2763,10 +3261,10 @@ var SurveySheet = ({ survey, api, p, onDone }) => {
|
|
|
2763
3261
|
};
|
|
2764
3262
|
var MRRocketSurveys = ({ client, appearance }) => {
|
|
2765
3263
|
const p = usePalette(appearance);
|
|
2766
|
-
const [survey, setSurvey] = (0,
|
|
2767
|
-
const [who2, setWho] = (0,
|
|
2768
|
-
(0,
|
|
2769
|
-
(0,
|
|
3264
|
+
const [survey, setSurvey] = (0, import_react3.useState)(null);
|
|
3265
|
+
const [who2, setWho] = (0, import_react3.useState)(() => client.getDistinctId());
|
|
3266
|
+
(0, import_react3.useEffect)(() => client.subscribe(() => setWho(client.getDistinctId())), [client]);
|
|
3267
|
+
(0, import_react3.useEffect)(() => {
|
|
2770
3268
|
let stop = false;
|
|
2771
3269
|
const ctrl = new AbortController();
|
|
2772
3270
|
const timer = setTimeout(() => {
|
|
@@ -2786,33 +3284,33 @@ var MRRocketSurveys = ({ client, appearance }) => {
|
|
|
2786
3284
|
ctrl.abort();
|
|
2787
3285
|
};
|
|
2788
3286
|
}, [client, who2]);
|
|
2789
|
-
const done = (0,
|
|
3287
|
+
const done = (0, import_react3.useCallback)(() => {
|
|
2790
3288
|
setSurvey((cur) => {
|
|
2791
3289
|
if (cur) client.markSurveyDone(cur.s.id);
|
|
2792
3290
|
return null;
|
|
2793
3291
|
});
|
|
2794
3292
|
}, [client]);
|
|
2795
3293
|
if (!survey) return null;
|
|
2796
|
-
return (0,
|
|
3294
|
+
return (0, import_react3.createElement)(SurveySheet, { key: survey.s.id, survey: survey.s, api: survey.api, p, onDone: done });
|
|
2797
3295
|
};
|
|
2798
3296
|
var feedbackOpen = opener();
|
|
2799
3297
|
var useFeedback = () => ({ open: () => feedbackOpen.set(true), close: () => feedbackOpen.set(false) });
|
|
2800
3298
|
var FeedbackSheet = ({ client, p, title }) => {
|
|
2801
3299
|
const k = kit(p);
|
|
2802
|
-
const [tab, setTab] = (0,
|
|
2803
|
-
const [posts, setPosts] = (0,
|
|
2804
|
-
const [boards, setBoards] = (0,
|
|
2805
|
-
const [error, setError] = (0,
|
|
2806
|
-
const [board, setBoard] = (0,
|
|
2807
|
-
const [subject, setSubject] = (0,
|
|
2808
|
-
const [details, setDetails] = (0,
|
|
2809
|
-
const [name, setName] = (0,
|
|
2810
|
-
const [email, setEmail] = (0,
|
|
2811
|
-
const [sending, setSending] = (0,
|
|
2812
|
-
const [sent, setSent] = (0,
|
|
3300
|
+
const [tab, setTab] = (0, import_react3.useState)("top");
|
|
3301
|
+
const [posts, setPosts] = (0, import_react3.useState)(null);
|
|
3302
|
+
const [boards, setBoards] = (0, import_react3.useState)([]);
|
|
3303
|
+
const [error, setError] = (0, import_react3.useState)("");
|
|
3304
|
+
const [board, setBoard] = (0, import_react3.useState)("feature");
|
|
3305
|
+
const [subject, setSubject] = (0, import_react3.useState)("");
|
|
3306
|
+
const [details, setDetails] = (0, import_react3.useState)("");
|
|
3307
|
+
const [name, setName] = (0, import_react3.useState)("");
|
|
3308
|
+
const [email, setEmail] = (0, import_react3.useState)("");
|
|
3309
|
+
const [sending, setSending] = (0, import_react3.useState)(false);
|
|
3310
|
+
const [sent, setSent] = (0, import_react3.useState)(false);
|
|
2813
3311
|
const close = () => feedbackOpen.set(false);
|
|
2814
3312
|
const user = client.getUser();
|
|
2815
|
-
(0,
|
|
3313
|
+
(0, import_react3.useEffect)(() => {
|
|
2816
3314
|
const api = client.api();
|
|
2817
3315
|
if (!api) return setError("Feedback is off while tracking is off.");
|
|
2818
3316
|
const ctrl = new AbortController();
|
|
@@ -2844,7 +3342,7 @@ var FeedbackSheet = ({ client, p, title }) => {
|
|
|
2844
3342
|
setSent(true);
|
|
2845
3343
|
}).catch((e) => setError(e.message)).finally(() => setSending(false));
|
|
2846
3344
|
};
|
|
2847
|
-
const tabs = (0,
|
|
3345
|
+
const tabs = (0, import_react3.createElement)(
|
|
2848
3346
|
RN3.View,
|
|
2849
3347
|
{ style: { flexDirection: "row", gap: 8, paddingHorizontal: 16, paddingTop: 12 } },
|
|
2850
3348
|
k.chip("Top requests", tab === "top", () => setTab("top")),
|
|
@@ -2853,17 +3351,17 @@ var FeedbackSheet = ({ client, p, title }) => {
|
|
|
2853
3351
|
setSent(false);
|
|
2854
3352
|
})
|
|
2855
3353
|
);
|
|
2856
|
-
const list = (0,
|
|
3354
|
+
const list = (0, import_react3.createElement)(
|
|
2857
3355
|
RN3.ScrollView,
|
|
2858
3356
|
{ style: { flex: 1 }, contentContainerStyle: { padding: 16, gap: 10 } },
|
|
2859
3357
|
error ? k.text(error, { color: p.danger, fontSize: 13 }) : null,
|
|
2860
3358
|
posts === null && !error ? k.muted("Loading\u2026") : null,
|
|
2861
3359
|
posts?.length === 0 ? k.muted("No requests yet. Be the first to suggest one.") : null,
|
|
2862
3360
|
...(posts ?? []).map(
|
|
2863
|
-
(post) => (0,
|
|
3361
|
+
(post) => (0, import_react3.createElement)(
|
|
2864
3362
|
RN3.View,
|
|
2865
3363
|
{ key: post.id, style: { flexDirection: "row", gap: 12, alignItems: "flex-start", paddingVertical: 8, borderBottomWidth: 1, borderBottomColor: p.line } },
|
|
2866
|
-
(0,
|
|
3364
|
+
(0, import_react3.createElement)(
|
|
2867
3365
|
RN3.Pressable,
|
|
2868
3366
|
{
|
|
2869
3367
|
onPress: () => vote(post),
|
|
@@ -2875,15 +3373,15 @@ var FeedbackSheet = ({ client, p, title }) => {
|
|
|
2875
3373
|
k.text("\u25B2", { fontSize: 11, color: post.voted ? p.accent : p.muted }),
|
|
2876
3374
|
k.text(String(post.votes), { fontWeight: "700", fontSize: 14, color: post.voted ? p.accent : p.fg })
|
|
2877
3375
|
),
|
|
2878
|
-
(0,
|
|
3376
|
+
(0, import_react3.createElement)(RN3.View, { style: { flex: 1, gap: 2 } }, k.text(post.title, { fontWeight: "600" }), post.body ? k.muted(post.body.slice(0, 160)) : null)
|
|
2879
3377
|
)
|
|
2880
3378
|
)
|
|
2881
3379
|
);
|
|
2882
|
-
const form = (0,
|
|
3380
|
+
const form = (0, import_react3.createElement)(
|
|
2883
3381
|
RN3.ScrollView,
|
|
2884
3382
|
{ style: { flex: 1 }, contentContainerStyle: { padding: 16, gap: 10 }, keyboardShouldPersistTaps: "handled" },
|
|
2885
3383
|
sent ? k.text("Thanks! Your request is on the board.", { fontWeight: "600" }) : null,
|
|
2886
|
-
boards.length > 1 ? (0,
|
|
3384
|
+
boards.length > 1 ? (0, import_react3.createElement)(RN3.View, { style: { flexDirection: "row", flexWrap: "wrap", gap: 6 } }, ...boards.map((b) => k.chip(b.label, board === b.id, () => setBoard(b.id), b.id))) : null,
|
|
2887
3385
|
k.field({ value: subject, onChange: setSubject, placeholder: "Short title", max: 120 }),
|
|
2888
3386
|
k.field({ value: details, onChange: setDetails, placeholder: "Details (optional)", multiline: true }),
|
|
2889
3387
|
...user?.email ? [] : [
|
|
@@ -2899,7 +3397,7 @@ var FeedbackSheet = ({ client, p, title }) => {
|
|
|
2899
3397
|
var MRRocketFeedback = ({ client, appearance, options = {} }) => {
|
|
2900
3398
|
const p = usePalette(appearance);
|
|
2901
3399
|
const open = feedbackOpen.useOpen();
|
|
2902
|
-
return open ? (0,
|
|
3400
|
+
return open ? (0, import_react3.createElement)(FeedbackSheet, { client, p, title: options.title ?? "Feedback" }) : null;
|
|
2903
3401
|
};
|
|
2904
3402
|
var POLL_OPEN_MS = 4e3;
|
|
2905
3403
|
var POLL_WAITING_MS = 8e3;
|
|
@@ -2939,11 +3437,11 @@ try {
|
|
|
2939
3437
|
}
|
|
2940
3438
|
var PHOTO_TYPES = { jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", webp: "image/webp", gif: "image/gif" };
|
|
2941
3439
|
var teamOf = (t) => (t?.messages ?? []).filter((m) => m.from !== "visitor");
|
|
2942
|
-
var
|
|
3440
|
+
var svg2 = null;
|
|
2943
3441
|
try {
|
|
2944
|
-
|
|
3442
|
+
svg2 = require("react-native-svg");
|
|
2945
3443
|
} catch {
|
|
2946
|
-
|
|
3444
|
+
svg2 = null;
|
|
2947
3445
|
}
|
|
2948
3446
|
var GLYPH = {
|
|
2949
3447
|
chat: "M2.5 4.5a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v4.5a2 2 0 0 1-2 2H7l-3 2.5V11a2 2 0 0 1-1.5-2z",
|
|
@@ -2958,15 +3456,15 @@ var GLYPH = {
|
|
|
2958
3456
|
};
|
|
2959
3457
|
var FALLBACK = { chat: "\u{1F4AC}", home: "\u2302", help: "?", send: "\u2192", up: "\u2191", next: "\u203A", search: "\u2315", cross: "\xD7", clip: "\u{1F4CE}" };
|
|
2960
3458
|
var glyph = (name, color, size = 20) => {
|
|
2961
|
-
const Svg =
|
|
2962
|
-
if (!
|
|
2963
|
-
return (0,
|
|
3459
|
+
const Svg = svg2?.Svg ?? svg2?.default;
|
|
3460
|
+
if (!svg2 || !Svg) return (0, import_react3.createElement)(RN3.Text, { style: { color, fontSize: Math.round(size * 0.85), lineHeight: size + 2, textAlign: "center", minWidth: size } }, FALLBACK[name]);
|
|
3461
|
+
return (0, import_react3.createElement)(Svg, { width: size, height: size, viewBox: "0 0 16 16", fill: "none" }, (0, import_react3.createElement)(svg2.Path, { d: GLYPH[name], stroke: color, strokeWidth: 1.7, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }));
|
|
2964
3462
|
};
|
|
2965
3463
|
var alpha = (hex, a) => /^#[0-9a-f]{6}$/i.test(hex) ? `${hex}${Math.round(a * 255).toString(16).padStart(2, "0")}` : hex;
|
|
2966
|
-
var teamMark = (title, bg, fg, size = 36) => (0,
|
|
3464
|
+
var teamMark = (title, bg, fg, size = 36) => (0, import_react3.createElement)(
|
|
2967
3465
|
RN3.View,
|
|
2968
3466
|
{ style: { width: size, height: size, borderRadius: size / 2, backgroundColor: bg, alignItems: "center", justifyContent: "center" } },
|
|
2969
|
-
(0,
|
|
3467
|
+
(0, import_react3.createElement)(RN3.Text, { style: { color: fg, fontSize: Math.round(size * 0.42), fontWeight: "700" } }, (title.trim()[0] ?? "?").toUpperCase())
|
|
2970
3468
|
);
|
|
2971
3469
|
var HU = {
|
|
2972
3470
|
light: { bg: "#ffffff", surface: "#f4f4f5", def: "#ececee", segment: "#ffffff", fg: "#18181b", muted: "#71717a" },
|
|
@@ -2974,20 +3472,20 @@ var HU = {
|
|
|
2974
3472
|
};
|
|
2975
3473
|
var hairline = { shadowColor: "#000", shadowOpacity: 0.07, shadowRadius: 3, shadowOffset: { width: 0, height: 1 }, elevation: 1 };
|
|
2976
3474
|
var useChat = (client, o, open, view) => {
|
|
2977
|
-
const [thread, setThread] = (0,
|
|
2978
|
-
const [loaded, setLoaded] = (0,
|
|
2979
|
-
const [error, setError] = (0,
|
|
2980
|
-
const [unseen, setUnseen] = (0,
|
|
2981
|
-
const known = (0,
|
|
3475
|
+
const [thread, setThread] = (0, import_react3.useState)(null);
|
|
3476
|
+
const [loaded, setLoaded] = (0, import_react3.useState)(false);
|
|
3477
|
+
const [error, setError] = (0, import_react3.useState)("");
|
|
3478
|
+
const [unseen, setUnseen] = (0, import_react3.useState)([]);
|
|
3479
|
+
const known = (0, import_react3.useRef)(null);
|
|
2982
3480
|
const watching = open && view === "messages";
|
|
2983
|
-
const watch = (0,
|
|
3481
|
+
const watch = (0, import_react3.useRef)(watching);
|
|
2984
3482
|
watch.current = watching;
|
|
2985
|
-
const [active, setActive] = (0,
|
|
2986
|
-
(0,
|
|
3483
|
+
const [active, setActive] = (0, import_react3.useState)(RN3.AppState.currentState === "active");
|
|
3484
|
+
(0, import_react3.useEffect)(() => {
|
|
2987
3485
|
const sub = RN3.AppState.addEventListener("change", (st) => setActive(st === "active"));
|
|
2988
3486
|
return () => sub.remove();
|
|
2989
3487
|
}, []);
|
|
2990
|
-
const take = (0,
|
|
3488
|
+
const take = (0, import_react3.useCallback)(
|
|
2991
3489
|
(t) => {
|
|
2992
3490
|
const team = teamOf(t);
|
|
2993
3491
|
if (known.current !== null) {
|
|
@@ -3003,10 +3501,10 @@ var useChat = (client, o, open, view) => {
|
|
|
3003
3501
|
},
|
|
3004
3502
|
[o.haptics]
|
|
3005
3503
|
);
|
|
3006
|
-
(0,
|
|
3504
|
+
(0, import_react3.useEffect)(() => {
|
|
3007
3505
|
if (watching) setUnseen([]);
|
|
3008
3506
|
}, [watching]);
|
|
3009
|
-
(0,
|
|
3507
|
+
(0, import_react3.useEffect)(() => {
|
|
3010
3508
|
if (!active) return;
|
|
3011
3509
|
let stop = false;
|
|
3012
3510
|
let timer;
|
|
@@ -3046,9 +3544,9 @@ var useChat = (client, o, open, view) => {
|
|
|
3046
3544
|
return { thread, loaded, error, setError, unseen, take };
|
|
3047
3545
|
};
|
|
3048
3546
|
var useArticles = (client, on, query) => {
|
|
3049
|
-
const [list, setList] = (0,
|
|
3050
|
-
const [any, setAny] = (0,
|
|
3051
|
-
(0,
|
|
3547
|
+
const [list, setList] = (0, import_react3.useState)(null);
|
|
3548
|
+
const [any, setAny] = (0, import_react3.useState)(null);
|
|
3549
|
+
(0, import_react3.useEffect)(() => {
|
|
3052
3550
|
if (!on) return;
|
|
3053
3551
|
let stop = false;
|
|
3054
3552
|
const t = setTimeout(
|
|
@@ -3069,7 +3567,7 @@ var useArticles = (client, on, query) => {
|
|
|
3069
3567
|
return { list, any };
|
|
3070
3568
|
};
|
|
3071
3569
|
var spansOf = (p, spans, base) => spans.map(
|
|
3072
|
-
(s, i) => (0,
|
|
3570
|
+
(s, i) => (0, import_react3.createElement)(
|
|
3073
3571
|
RN3.Text,
|
|
3074
3572
|
{
|
|
3075
3573
|
key: i,
|
|
@@ -3088,10 +3586,10 @@ var spansOf = (p, spans, base) => spans.map(
|
|
|
3088
3586
|
);
|
|
3089
3587
|
var ArticleView = ({ client, p, id, onAsk }) => {
|
|
3090
3588
|
const k = kit(p);
|
|
3091
|
-
const [a, setA] = (0,
|
|
3092
|
-
const [error, setError] = (0,
|
|
3093
|
-
const [rated, setRated] = (0,
|
|
3094
|
-
(0,
|
|
3589
|
+
const [a, setA] = (0, import_react3.useState)(null);
|
|
3590
|
+
const [error, setError] = (0, import_react3.useState)("");
|
|
3591
|
+
const [rated, setRated] = (0, import_react3.useState)(false);
|
|
3592
|
+
(0, import_react3.useEffect)(() => {
|
|
3095
3593
|
const ctrl = new AbortController();
|
|
3096
3594
|
client.api()?.article(id, ctrl.signal).then(setA).catch((e) => e.name !== "AbortError" && setError(e.message));
|
|
3097
3595
|
return () => ctrl.abort();
|
|
@@ -3100,30 +3598,30 @@ var ArticleView = ({ client, p, id, onAsk }) => {
|
|
|
3100
3598
|
if (!a) return k.muted("Loading\u2026");
|
|
3101
3599
|
const base = { color: p.fg, fontSize: 15, lineHeight: 22 };
|
|
3102
3600
|
const blocks = a.blocks.map((b, i) => {
|
|
3103
|
-
if (b.type === "h2" || b.type === "h3") return (0,
|
|
3104
|
-
if (b.type === "p") return (0,
|
|
3105
|
-
if (b.type === "quote") return (0,
|
|
3601
|
+
if (b.type === "h2" || b.type === "h3") return (0, import_react3.createElement)(RN3.Text, { key: i, accessibilityRole: "header", style: { ...base, fontSize: b.type === "h2" ? 17 : 16, fontWeight: "700", marginTop: 8 } }, ...spansOf(p, b.spans, {}));
|
|
3602
|
+
if (b.type === "p") return (0, import_react3.createElement)(RN3.Text, { key: i, style: base }, ...spansOf(p, b.spans, {}));
|
|
3603
|
+
if (b.type === "quote") return (0, import_react3.createElement)(RN3.View, { key: i, style: { borderLeftWidth: 3, borderLeftColor: p.line, paddingLeft: 10 } }, (0, import_react3.createElement)(RN3.Text, { style: { ...base, color: p.muted } }, ...spansOf(p, b.spans, {})));
|
|
3106
3604
|
if (b.type === "ul" || b.type === "ol")
|
|
3107
|
-
return (0,
|
|
3605
|
+
return (0, import_react3.createElement)(
|
|
3108
3606
|
RN3.View,
|
|
3109
3607
|
{ key: i, style: { gap: 4 } },
|
|
3110
|
-
...b.items.map((it, j) => (0,
|
|
3608
|
+
...b.items.map((it, j) => (0, import_react3.createElement)(RN3.View, { key: j, style: { flexDirection: "row", gap: 8 } }, k.text(b.type === "ol" ? `${j + 1}.` : "\u2022", base), (0, import_react3.createElement)(RN3.Text, { style: { ...base, flex: 1 } }, ...spansOf(p, it, {}))))
|
|
3111
3609
|
);
|
|
3112
|
-
if (b.type === "code") return (0,
|
|
3113
|
-
return (0,
|
|
3610
|
+
if (b.type === "code") return (0, import_react3.createElement)(RN3.View, { key: i, style: { backgroundColor: p.soft, borderRadius: 8, padding: 10 } }, k.text(b.text, { fontFamily: RN3.Platform.OS === "ios" ? "Menlo" : "monospace", fontSize: 13 }));
|
|
3611
|
+
return (0, import_react3.createElement)(RN3.View, { key: i, style: { height: 1, backgroundColor: p.line } });
|
|
3114
3612
|
});
|
|
3115
3613
|
const rate = (helpful) => {
|
|
3116
3614
|
setRated(true);
|
|
3117
3615
|
client.api()?.rateArticle(id, helpful).catch(() => void 0);
|
|
3118
3616
|
if (!helpful) onAsk();
|
|
3119
3617
|
};
|
|
3120
|
-
return (0,
|
|
3618
|
+
return (0, import_react3.createElement)(
|
|
3121
3619
|
RN3.View,
|
|
3122
3620
|
{ style: { gap: 10 } },
|
|
3123
3621
|
k.muted(a.collection),
|
|
3124
|
-
(0,
|
|
3622
|
+
(0, import_react3.createElement)(RN3.Text, { accessibilityRole: "header", style: { color: p.fg, fontSize: 20, fontWeight: "700" } }, a.title),
|
|
3125
3623
|
...blocks,
|
|
3126
|
-
(0,
|
|
3624
|
+
(0, import_react3.createElement)(
|
|
3127
3625
|
RN3.View,
|
|
3128
3626
|
{ style: { flexDirection: "row", alignItems: "center", gap: 8, padding: 12, borderRadius: 10, backgroundColor: p.soft, marginTop: 8 } },
|
|
3129
3627
|
rated ? k.muted("Thanks for letting us know.") : k.muted("Did this answer your question?", { flex: 1 }),
|
|
@@ -3143,19 +3641,26 @@ var MessengerSheet = ({
|
|
|
3143
3641
|
brand
|
|
3144
3642
|
}) => {
|
|
3145
3643
|
const k = kit(p);
|
|
3146
|
-
const [body, setBody] = (0,
|
|
3147
|
-
const [email, setEmail] = (0,
|
|
3148
|
-
const [pending, setPending] = (0,
|
|
3149
|
-
const [
|
|
3150
|
-
|
|
3644
|
+
const [body, setBody] = (0, import_react3.useState)("");
|
|
3645
|
+
const [email, setEmail] = (0, import_react3.useState)("");
|
|
3646
|
+
const [pending, setPending] = (0, import_react3.useState)(null);
|
|
3647
|
+
const [slow, setSlow] = (0, import_react3.useState)(false);
|
|
3648
|
+
(0, import_react3.useEffect)(() => {
|
|
3649
|
+
setSlow(false);
|
|
3650
|
+
if (!pending) return;
|
|
3651
|
+
const t = setTimeout(() => setSlow(true), 1500);
|
|
3652
|
+
return () => clearTimeout(t);
|
|
3653
|
+
}, [pending]);
|
|
3654
|
+
const [photos, setPhotos] = (0, import_react3.useState)([]);
|
|
3655
|
+
const [query, setQuery] = (0, import_react3.useState)("");
|
|
3151
3656
|
const helpOn = o.help !== false;
|
|
3152
3657
|
const arts = useArticles(client, helpOn, query);
|
|
3153
|
-
const scroll = (0,
|
|
3658
|
+
const scroll = (0, import_react3.useRef)(null);
|
|
3154
3659
|
const close = () => messengerOpen.set(false);
|
|
3155
3660
|
const greeting = o.greeting ?? "Hi! How can we help?";
|
|
3156
3661
|
const { thread } = chat;
|
|
3157
3662
|
const count = (thread?.messages.length ?? 0) + (pending ? 1 : 0);
|
|
3158
|
-
(0,
|
|
3663
|
+
(0, import_react3.useEffect)(() => {
|
|
3159
3664
|
if (view === "messages") setTimeout(() => scroll.current?.scrollToEnd?.({ animated: true }), 50);
|
|
3160
3665
|
}, [count, view]);
|
|
3161
3666
|
const needEmail = (o.askEmail ?? true) && !thread?.hasEmail && !client.getUser()?.email;
|
|
@@ -3238,7 +3743,7 @@ var MessengerSheet = ({
|
|
|
3238
3743
|
setPending(null);
|
|
3239
3744
|
}
|
|
3240
3745
|
};
|
|
3241
|
-
const localUris = (0,
|
|
3746
|
+
const localUris = (0, import_react3.useRef)(/* @__PURE__ */ new Map());
|
|
3242
3747
|
for (const f of photos) localUris.current.set(f.key, f.uri);
|
|
3243
3748
|
const fileUrl = (id) => localUris.current.get(id) ?? client.api()?.attachmentUrl(id) ?? "";
|
|
3244
3749
|
const ink = inkOn(p.accent);
|
|
@@ -3253,11 +3758,11 @@ var MessengerSheet = ({
|
|
|
3253
3758
|
const title = o.title?.trim() ?? "";
|
|
3254
3759
|
const bubble = (m, isPending = false) => {
|
|
3255
3760
|
const mine = m.from === "visitor";
|
|
3256
|
-
return (0,
|
|
3761
|
+
return (0, import_react3.createElement)(
|
|
3257
3762
|
RN3.View,
|
|
3258
3763
|
{ key: m.id, style: { alignSelf: mine ? "flex-end" : "flex-start", maxWidth: "82%", gap: 4 } },
|
|
3259
3764
|
...(m.attachments ?? []).map(
|
|
3260
|
-
(f) => (0,
|
|
3765
|
+
(f) => (0, import_react3.createElement)(
|
|
3261
3766
|
RN3.Pressable,
|
|
3262
3767
|
{
|
|
3263
3768
|
key: f.id,
|
|
@@ -3266,10 +3771,10 @@ var MessengerSheet = ({
|
|
|
3266
3771
|
accessibilityLabel: f.name,
|
|
3267
3772
|
style: { alignSelf: mine ? "flex-end" : "flex-start", opacity: isPending ? 0.7 : 1 }
|
|
3268
3773
|
},
|
|
3269
|
-
f.type.startsWith("image/") ? (0,
|
|
3774
|
+
f.type.startsWith("image/") ? (0, import_react3.createElement)(RN3.Image, { source: { uri: fileUrl(f.id) }, resizeMode: "cover", style: { width: 200, height: 150, borderRadius: r.bubble, backgroundColor: p.soft } }) : (0, import_react3.createElement)(RN3.View, { style: { backgroundColor: p.soft, borderRadius: r.card, paddingHorizontal: 10, paddingVertical: 7 } }, k.text(`\u{1F4C4} ${f.name}`, { fontSize: 13 }))
|
|
3270
3775
|
)
|
|
3271
3776
|
),
|
|
3272
|
-
!m.body && m.attachments?.length ? null : (0,
|
|
3777
|
+
!m.body && m.attachments?.length ? null : (0, import_react3.createElement)(
|
|
3273
3778
|
RN3.View,
|
|
3274
3779
|
{
|
|
3275
3780
|
style: {
|
|
@@ -3286,23 +3791,23 @@ var MessengerSheet = ({
|
|
|
3286
3791
|
k.text(m.body, { color: mine ? ink : hu.fg })
|
|
3287
3792
|
),
|
|
3288
3793
|
...(m.articles ?? []).map(
|
|
3289
|
-
(a) => (0,
|
|
3794
|
+
(a) => (0, import_react3.createElement)(
|
|
3290
3795
|
RN3.Pressable,
|
|
3291
3796
|
{ key: a.id, onPress: () => setView({ article: a.id }), accessibilityRole: "link", style: { backgroundColor: p.soft, borderRadius: r.card, paddingHorizontal: 10, paddingVertical: 7 } },
|
|
3292
3797
|
k.text(`\u{1F4C4} ${a.title}`, { fontSize: 13 })
|
|
3293
3798
|
)
|
|
3294
3799
|
),
|
|
3295
|
-
m.at ? k.muted(`${mine ? "" : `${who(m.from, o.agentName)} \xB7 `}${isPending ? "Sending\u2026" : timeAgo(m.at)}`, { fontSize: 11, textAlign: mine ? "right" : "left", paddingHorizontal: 6 }) : null
|
|
3800
|
+
m.at ? k.muted(`${mine ? "" : `${who(m.from, o.agentName)} \xB7 `}${isPending && slow ? "Sending\u2026" : timeAgo(m.at)}`, { fontSize: 11, textAlign: mine ? "right" : "left", paddingHorizontal: 6 }) : null
|
|
3296
3801
|
);
|
|
3297
3802
|
};
|
|
3298
|
-
const row = (a) => (0,
|
|
3803
|
+
const row = (a) => (0, import_react3.createElement)(
|
|
3299
3804
|
RN3.Pressable,
|
|
3300
3805
|
{ key: a.id, onPress: () => setView({ article: a.id }), accessibilityRole: "button", style: { flexDirection: "row", alignItems: "center", gap: 8, paddingVertical: 11, paddingHorizontal: 8 } },
|
|
3301
3806
|
k.text(a.title, { flex: 1 }),
|
|
3302
3807
|
glyph("next", p.accent, 14)
|
|
3303
3808
|
);
|
|
3304
|
-
const card = (children, style = {}) => (0,
|
|
3305
|
-
const searchRow = (onPress) => (0,
|
|
3809
|
+
const card = (children, style = {}) => (0, import_react3.createElement)(RN3.View, { style: { backgroundColor: raised, borderRadius: r.card, padding: 16, ...surf, ...style } }, ...children);
|
|
3810
|
+
const searchRow = (onPress) => (0, import_react3.createElement)(
|
|
3306
3811
|
RN3.Pressable,
|
|
3307
3812
|
{ key: "s", onPress, accessibilityRole: "search", style: { flexDirection: "row", alignItems: "center", height: 44, borderRadius: r.field, paddingHorizontal: 14, backgroundColor: hu.def } },
|
|
3308
3813
|
k.muted("Search for help", { flex: 1, fontSize: 15 }),
|
|
@@ -3311,12 +3816,12 @@ var MessengerSheet = ({
|
|
|
3311
3816
|
const search = k.field({ value: query, onChange: setQuery, placeholder: "Search for help", max: 200, style: { borderWidth: 0, borderRadius: r.field, backgroundColor: raised, ...surf } });
|
|
3312
3817
|
const first = client.getUser()?.name?.trim().split(/\s+/)[0];
|
|
3313
3818
|
const rest = greeting.replace(/^(hi|hello|hey|hallo)( there)?\s*[!,.]*\s*/i, "").trim() || "How can we help you today?";
|
|
3314
|
-
const hero = (fg, sub) => (0,
|
|
3819
|
+
const hero = (fg, sub) => (0, import_react3.createElement)(
|
|
3315
3820
|
RN3.Text,
|
|
3316
3821
|
{ key: "hero", accessibilityRole: "header", style: { color: fg, fontSize: 25, fontWeight: "600", letterSpacing: -0.6, lineHeight: 30 } },
|
|
3317
3822
|
first ? `Hi, ${first} \u{1F44B}
|
|
3318
3823
|
` : "Hi there \u{1F44B}\n",
|
|
3319
|
-
(0,
|
|
3824
|
+
(0, import_react3.createElement)(RN3.Text, { style: { color: sub, fontWeight: "500" } }, rest)
|
|
3320
3825
|
);
|
|
3321
3826
|
const last = thread?.messages.at(-1);
|
|
3322
3827
|
const showHelp = helpOn && arts.any !== false;
|
|
@@ -3324,11 +3829,11 @@ var MessengerSheet = ({
|
|
|
3324
3829
|
if (view === "home") {
|
|
3325
3830
|
const cards = [
|
|
3326
3831
|
// "Ask a question": the words go into the chat's field and are sent as the chat opens.
|
|
3327
|
-
(0,
|
|
3832
|
+
(0, import_react3.createElement)(
|
|
3328
3833
|
RN3.View,
|
|
3329
3834
|
{ key: "ask", style: { flexDirection: "row", alignItems: "center", gap: 8, height: 48, borderRadius: 24, paddingLeft: 18, paddingRight: 6, backgroundColor: hu.surface, ...surf } },
|
|
3330
3835
|
k.field({ value: body, onChange: setBody, placeholder: "Ask a question", max: 4e3, style: { flex: 1, borderWidth: 0, paddingHorizontal: 0, backgroundColor: "transparent" } }),
|
|
3331
|
-
(0,
|
|
3836
|
+
(0, import_react3.createElement)(
|
|
3332
3837
|
RN3.Pressable,
|
|
3333
3838
|
{
|
|
3334
3839
|
onPress: () => {
|
|
@@ -3342,59 +3847,60 @@ var MessengerSheet = ({
|
|
|
3342
3847
|
glyph("up", body.trim() ? ink : hu.muted, 18)
|
|
3343
3848
|
)
|
|
3344
3849
|
),
|
|
3345
|
-
last ? (0,
|
|
3850
|
+
last ? (0, import_react3.createElement)(
|
|
3346
3851
|
RN3.Pressable,
|
|
3347
3852
|
{ key: "recent", onPress: () => setView("messages"), accessibilityRole: "button" },
|
|
3348
3853
|
card([
|
|
3349
|
-
(0,
|
|
3854
|
+
(0, import_react3.createElement)(
|
|
3350
3855
|
RN3.View,
|
|
3351
3856
|
{ key: "r", style: { flexDirection: "row", alignItems: "center", gap: 10 } },
|
|
3352
3857
|
title ? teamMark(title, alpha(p.accent, 0.16), p.accent, 26) : null,
|
|
3353
|
-
(0,
|
|
3354
|
-
chat.unseen.length ? (0,
|
|
3858
|
+
(0, import_react3.createElement)(RN3.View, { style: { flex: 1, gap: 1 } }, (0, import_react3.createElement)(RN3.Text, { numberOfLines: 1, style: { color: hu.fg, fontSize: 14, fontWeight: "500" } }, last.body || (last.attachments?.length ? `Sent ${last.attachments.length === 1 ? last.attachments[0].name : `${last.attachments.length} files`}` : "")), k.muted(`${last.from === "visitor" ? "You" : who(last.from, o.agentName)} \xB7 ${timeAgo(last.at)}`, { fontSize: 11.5 })),
|
|
3859
|
+
chat.unseen.length ? (0, import_react3.createElement)(RN3.View, { style: { width: 8, height: 8, borderRadius: 4, backgroundColor: p.danger } }) : glyph("next", p.muted, 14)
|
|
3355
3860
|
)
|
|
3356
3861
|
], { paddingVertical: 10, paddingHorizontal: 12 })
|
|
3357
3862
|
) : null,
|
|
3358
3863
|
showHelp ? card([searchRow(() => setView("help")), ...(arts.list ?? []).slice(0, 4).map(row)], { padding: 8, gap: 2 }) : null
|
|
3359
3864
|
];
|
|
3360
|
-
content = plain ? (0,
|
|
3865
|
+
content = plain ? (0, import_react3.createElement)(
|
|
3361
3866
|
RN3.ScrollView,
|
|
3362
3867
|
{ key: "home", style: { flex: 1, backgroundColor: canvas }, contentContainerStyle: { paddingHorizontal: 16, paddingTop: 4, paddingBottom: 24, gap: 12 }, keyboardShouldPersistTaps: "handled" },
|
|
3363
|
-
(0,
|
|
3868
|
+
(0, import_react3.createElement)(RN3.View, { key: "top", style: { paddingHorizontal: 6, paddingBottom: 10 } }, hero(p.fg, p.muted)),
|
|
3364
3869
|
...cards
|
|
3365
|
-
) : (0,
|
|
3870
|
+
) : (0, import_react3.createElement)(
|
|
3366
3871
|
RN3.ScrollView,
|
|
3367
3872
|
{ key: "home", style: { flex: 1, backgroundColor: canvas }, contentContainerStyle: { paddingBottom: 24 }, keyboardShouldPersistTaps: "handled" },
|
|
3368
|
-
(0,
|
|
3369
|
-
(0,
|
|
3873
|
+
(0, import_react3.createElement)(RN3.View, { style: { backgroundColor: p.accent, paddingHorizontal: 22, paddingTop: 4, paddingBottom: 64 } }, hero(ink, alpha(ink, 0.8))),
|
|
3874
|
+
(0, import_react3.createElement)(RN3.View, { style: { marginTop: -48, paddingHorizontal: 16, gap: 12 } }, ...cards)
|
|
3370
3875
|
);
|
|
3371
3876
|
} else if (view === "messages")
|
|
3372
|
-
content = (0,
|
|
3877
|
+
content = (0, import_react3.createElement)(
|
|
3373
3878
|
RN3.View,
|
|
3374
3879
|
{ key: "messages", style: { flex: 1, backgroundColor: hu.bg } },
|
|
3375
|
-
(0,
|
|
3880
|
+
(0, import_react3.createElement)(
|
|
3376
3881
|
RN3.ScrollView,
|
|
3377
3882
|
{ ref: scroll, style: { flex: 1 }, contentContainerStyle: { paddingHorizontal: 16, paddingTop: 4, paddingBottom: 16, gap: 12 } },
|
|
3378
|
-
|
|
3883
|
+
// The greeting opens an empty chat only, never above the visitor's first words (2026-10-30).
|
|
3884
|
+
!thread?.messages.length && !pending ? bubble({ id: "greeting", from: "team", body: greeting, at: "" }) : null,
|
|
3379
3885
|
!chat.loaded ? k.muted("Loading\u2026") : null,
|
|
3380
3886
|
...(thread?.messages ?? []).map((m) => bubble(m)),
|
|
3381
3887
|
pending ? bubble(pending, true) : null,
|
|
3382
3888
|
thread?.conversation?.status === "solved" && !pending ? k.muted("This conversation is closed. Write to start a new one.", { textAlign: "center" }) : null
|
|
3383
3889
|
),
|
|
3384
|
-
(0,
|
|
3890
|
+
(0, import_react3.createElement)(
|
|
3385
3891
|
RN3.View,
|
|
3386
3892
|
{ style: { paddingHorizontal: 12, paddingTop: 8, paddingBottom: 6, gap: 8 } },
|
|
3387
3893
|
chat.error ? k.text(chat.error, { color: p.danger, fontSize: 12 }) : null,
|
|
3388
3894
|
// Photos picked for the next message, each with a way to take it out again.
|
|
3389
|
-
photos.length ? (0,
|
|
3895
|
+
photos.length ? (0, import_react3.createElement)(
|
|
3390
3896
|
RN3.View,
|
|
3391
3897
|
{ style: { flexDirection: "row", flexWrap: "wrap", gap: 10, paddingTop: 6, paddingHorizontal: 2 } },
|
|
3392
3898
|
...photos.map(
|
|
3393
|
-
(f) => (0,
|
|
3899
|
+
(f) => (0, import_react3.createElement)(
|
|
3394
3900
|
RN3.View,
|
|
3395
3901
|
{ key: f.key, style: { width: 56, height: 56 } },
|
|
3396
|
-
(0,
|
|
3397
|
-
(0,
|
|
3902
|
+
(0, import_react3.createElement)(RN3.Image, { source: { uri: f.uri }, resizeMode: "cover", accessibilityLabel: f.id ? f.name : `${f.name}, uploading`, style: { width: 56, height: 56, borderRadius: Math.max(4, r.card - 4), backgroundColor: p.soft, opacity: f.id ? 1 : 0.5 } }),
|
|
3903
|
+
(0, import_react3.createElement)(
|
|
3398
3904
|
RN3.Pressable,
|
|
3399
3905
|
{
|
|
3400
3906
|
onPress: () => setPhotos((list) => list.filter((x) => x.key !== f.key)),
|
|
@@ -3409,7 +3915,7 @@ var MessengerSheet = ({
|
|
|
3409
3915
|
)
|
|
3410
3916
|
) : null,
|
|
3411
3917
|
// The message field on top, the paperclip (when the app has expo-image-picker) and the send button under it.
|
|
3412
|
-
(0,
|
|
3918
|
+
(0, import_react3.createElement)(
|
|
3413
3919
|
RN3.View,
|
|
3414
3920
|
{ style: { gap: 2, borderRadius: 20, paddingTop: 10, paddingBottom: 6, paddingRight: 6, paddingLeft: 16, backgroundColor: hu.surface, ...surf } },
|
|
3415
3921
|
// The optional email: the box's first line, under a hairline the message follows.
|
|
@@ -3422,16 +3928,16 @@ var MessengerSheet = ({
|
|
|
3422
3928
|
style: { minHeight: 0, marginRight: 10, marginBottom: 4, paddingHorizontal: 0, paddingTop: 0, paddingBottom: 8, borderWidth: 0, borderRadius: 0, borderBottomWidth: 1, borderBottomColor: emailOk ? p.line : p.danger, backgroundColor: "transparent", fontSize: 13.5 }
|
|
3423
3929
|
}) : null,
|
|
3424
3930
|
k.field({ value: body, onChange: setBody, placeholder: "Write a message\u2026", multiline: true, max: 4e3, style: { minHeight: 28, maxHeight: 120, borderWidth: 0, paddingHorizontal: 0, paddingVertical: 4, backgroundColor: "transparent" } }),
|
|
3425
|
-
(0,
|
|
3931
|
+
(0, import_react3.createElement)(
|
|
3426
3932
|
RN3.View,
|
|
3427
3933
|
{ style: { flexDirection: "row", alignItems: "center", marginLeft: -8 } },
|
|
3428
|
-
imagePicker?.launchImageLibraryAsync ? (0,
|
|
3934
|
+
imagePicker?.launchImageLibraryAsync ? (0, import_react3.createElement)(
|
|
3429
3935
|
RN3.Pressable,
|
|
3430
3936
|
{ onPress: () => void pickPhotos(), disabled: !!pending, accessibilityRole: "button", accessibilityLabel: "Attach a photo or screenshot", hitSlop: 6, style: { width: 34, height: 34, borderRadius: 17, alignItems: "center", justifyContent: "center" } },
|
|
3431
3937
|
glyph("clip", hu.muted, 19)
|
|
3432
3938
|
) : null,
|
|
3433
|
-
(0,
|
|
3434
|
-
(0,
|
|
3939
|
+
(0, import_react3.createElement)(RN3.View, { style: { flex: 1 } }),
|
|
3940
|
+
(0, import_react3.createElement)(
|
|
3435
3941
|
RN3.Pressable,
|
|
3436
3942
|
{
|
|
3437
3943
|
onPress: () => void send(),
|
|
@@ -3449,24 +3955,24 @@ var MessengerSheet = ({
|
|
|
3449
3955
|
else if (view === "help") {
|
|
3450
3956
|
const groups = /* @__PURE__ */ new Map();
|
|
3451
3957
|
for (const a of arts.list ?? []) groups.set(a.collection, [...groups.get(a.collection) ?? [], a]);
|
|
3452
|
-
content = (0,
|
|
3958
|
+
content = (0, import_react3.createElement)(
|
|
3453
3959
|
RN3.ScrollView,
|
|
3454
3960
|
{ key: "help", style: { flex: 1, backgroundColor: canvas }, contentContainerStyle: { paddingHorizontal: 16, paddingTop: 4, paddingBottom: 16, gap: 12 }, keyboardShouldPersistTaps: "handled" },
|
|
3455
3961
|
search,
|
|
3456
3962
|
arts.list === null ? k.muted("Loading\u2026") : null,
|
|
3457
|
-
arts.list?.length === 0 ? (0,
|
|
3458
|
-
...query.trim() ? arts.list?.length ? [card((arts.list ?? []).map(row), { padding: 8 })] : [] : [...groups].map(([name, items]) => (0,
|
|
3963
|
+
arts.list?.length === 0 ? (0, import_react3.createElement)(RN3.View, { style: { gap: 10, alignItems: "center", paddingVertical: 24 } }, k.muted(query.trim() ? `Nothing found for \u201C${query.trim()}\u201D.` : "No help articles yet."), k.btn("Send us a message", "primary", () => setView("messages"))) : null,
|
|
3964
|
+
...query.trim() ? arts.list?.length ? [card((arts.list ?? []).map(row), { padding: 8 })] : [] : [...groups].map(([name, items]) => (0, import_react3.createElement)(RN3.View, { key: name, style: { gap: 6 } }, k.muted(`${name} \xB7 ${items.length}`, { fontSize: 12, fontWeight: "600", paddingHorizontal: 2 }), card(items.map(row), { padding: 8 })))
|
|
3459
3965
|
);
|
|
3460
3966
|
} else
|
|
3461
|
-
content = (0,
|
|
3967
|
+
content = (0, import_react3.createElement)(
|
|
3462
3968
|
RN3.ScrollView,
|
|
3463
3969
|
{ key: `a-${view.article}`, style: { flex: 1 }, contentContainerStyle: { paddingHorizontal: 16, paddingTop: 4, paddingBottom: 32 } },
|
|
3464
|
-
(0,
|
|
3970
|
+
(0, import_react3.createElement)(ArticleView, { client, p, id: view.article, onAsk: () => setView("messages") })
|
|
3465
3971
|
);
|
|
3466
3972
|
const current = typeof view === "string" ? view : "help";
|
|
3467
3973
|
const tab = (v, name, icon, badge = 0) => {
|
|
3468
3974
|
const on = current === v;
|
|
3469
|
-
return (0,
|
|
3975
|
+
return (0, import_react3.createElement)(
|
|
3470
3976
|
RN3.Pressable,
|
|
3471
3977
|
{
|
|
3472
3978
|
key: v,
|
|
@@ -3479,48 +3985,48 @@ var MessengerSheet = ({
|
|
|
3479
3985
|
},
|
|
3480
3986
|
glyph(icon, on ? hu.fg : hu.muted, 17),
|
|
3481
3987
|
on ? k.text(name, { fontSize: 13.5, fontWeight: "500", color: hu.fg }) : null,
|
|
3482
|
-
badge ? (0,
|
|
3988
|
+
badge ? (0, import_react3.createElement)(RN3.View, { style: { position: "absolute", top: 7, right: 12, width: 8, height: 8, borderRadius: 4, backgroundColor: p.danger } }) : null
|
|
3483
3989
|
);
|
|
3484
3990
|
};
|
|
3485
3991
|
const onAccent = view === "home" && !plain;
|
|
3486
3992
|
const ground = onAccent ? p.accent : hu.bg;
|
|
3487
|
-
const back = (to, label) => (0,
|
|
3993
|
+
const back = (to, label) => (0, import_react3.createElement)(
|
|
3488
3994
|
RN3.Pressable,
|
|
3489
3995
|
{ key: "back", onPress: () => setView(to), accessibilityRole: "button", accessibilityLabel: label, hitSlop: 10, style: { width: 32, height: 32, alignItems: "center", justifyContent: "center", transform: [{ rotate: "180deg" }] } },
|
|
3490
3996
|
glyph("next", hu.fg, 18)
|
|
3491
3997
|
);
|
|
3492
|
-
const head = (0,
|
|
3998
|
+
const head = (0, import_react3.createElement)(
|
|
3493
3999
|
RN3.View,
|
|
3494
4000
|
{ key: "head", style: { flexDirection: "row", alignItems: "center", gap: 8, paddingLeft: 12, paddingRight: 12, paddingTop: 12, paddingBottom: 6, backgroundColor: ground } },
|
|
3495
|
-
typeof view !== "string" ? back("help", "All articles") : view === "messages" ? back("home", "Back to home") : view === "home" && (o.logo || title) ? o.logo ? (0,
|
|
4001
|
+
typeof view !== "string" ? back("help", "All articles") : view === "messages" ? back("home", "Back to home") : view === "home" && (o.logo || title) ? o.logo ? (0, import_react3.createElement)(RN3.Image, { key: "logo", source: { uri: o.logo }, accessibilityIgnoresInvertColors: true, resizeMode: "contain", style: { height: 28, aspectRatio: 1, maxWidth: 132, borderRadius: 8, marginLeft: 4 } }) : teamMark(title, alpha(p.accent, 0.16), p.accent, 28) : null,
|
|
3496
4002
|
// In the chat: who answers, in the middle.
|
|
3497
|
-
view === "messages" && title ? (0,
|
|
4003
|
+
view === "messages" && title ? (0, import_react3.createElement)(
|
|
3498
4004
|
RN3.View,
|
|
3499
4005
|
{ style: { flex: 1, flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 8 } },
|
|
3500
4006
|
teamMark(title, alpha(p.accent, 0.16), p.accent, 28),
|
|
3501
|
-
(0,
|
|
3502
|
-
) : (0,
|
|
3503
|
-
(0,
|
|
4007
|
+
(0, import_react3.createElement)(RN3.Text, { numberOfLines: 1, style: { flexShrink: 1, color: hu.fg, fontSize: 15, fontWeight: "600" } }, title)
|
|
4008
|
+
) : (0, import_react3.createElement)(RN3.View, { style: { flex: 1 } }),
|
|
4009
|
+
(0, import_react3.createElement)(RN3.Pressable, { onPress: close, accessibilityRole: "button", accessibilityLabel: "Close", hitSlop: 12, style: { width: 32, height: 32, borderRadius: 10, alignItems: "center", justifyContent: "center" } }, glyph("cross", onAccent ? ink : p.muted, 18))
|
|
3504
4010
|
);
|
|
3505
|
-
const powered = brand ? (0,
|
|
4011
|
+
const powered = brand ? (0, import_react3.createElement)(
|
|
3506
4012
|
RN3.View,
|
|
3507
4013
|
{ key: "brand", style: { paddingTop: 2, paddingBottom: 6, alignItems: "center", backgroundColor: hu.bg } },
|
|
3508
|
-
(0,
|
|
4014
|
+
(0, import_react3.createElement)(
|
|
3509
4015
|
RN3.Text,
|
|
3510
4016
|
{ onPress: () => void RN3.Linking.openURL(BRAND_URL).catch(() => void 0), accessibilityRole: "link", hitSlop: 8, style: { color: p.muted, fontSize: 11.5 } },
|
|
3511
4017
|
"Powered by ",
|
|
3512
|
-
(0,
|
|
4018
|
+
(0, import_react3.createElement)(RN3.Text, { style: { fontWeight: "600" } }, "MRRocket")
|
|
3513
4019
|
)
|
|
3514
4020
|
) : null;
|
|
3515
|
-
return (0,
|
|
4021
|
+
return (0, import_react3.createElement)(
|
|
3516
4022
|
RN3.Modal,
|
|
3517
4023
|
{ visible: true, animationType: "slide", presentationStyle: "pageSheet", onRequestClose: close },
|
|
3518
|
-
(0,
|
|
4024
|
+
(0, import_react3.createElement)(
|
|
3519
4025
|
RN3.KeyboardAvoidingView,
|
|
3520
4026
|
{ behavior: RN3.Platform.OS === "ios" ? "padding" : void 0, style: { flex: 1, backgroundColor: hu.bg } },
|
|
3521
4027
|
head,
|
|
3522
4028
|
content,
|
|
3523
|
-
view === "messages" ? null : (0,
|
|
4029
|
+
view === "messages" ? null : (0, import_react3.createElement)(
|
|
3524
4030
|
RN3.View,
|
|
3525
4031
|
{ key: "tabs", accessibilityRole: "tablist", style: { flexDirection: "row", marginHorizontal: 12, marginTop: 6, marginBottom: 6, padding: 4, borderRadius: 22, backgroundColor: hu.surface } },
|
|
3526
4032
|
tab("home", "Home", "home"),
|
|
@@ -3528,13 +4034,13 @@ var MessengerSheet = ({
|
|
|
3528
4034
|
showHelp ? tab("help", "Help", "help") : null
|
|
3529
4035
|
),
|
|
3530
4036
|
powered,
|
|
3531
|
-
(0,
|
|
4037
|
+
(0, import_react3.createElement)(RN3.View, { style: { height: 16 } })
|
|
3532
4038
|
)
|
|
3533
4039
|
);
|
|
3534
4040
|
};
|
|
3535
4041
|
var MRRocketMessenger = ({ client, appearance, options: given = {} }) => {
|
|
3536
|
-
const [look, setLook] = (0,
|
|
3537
|
-
(0,
|
|
4042
|
+
const [look, setLook] = (0, import_react3.useState)(null);
|
|
4043
|
+
(0, import_react3.useEffect)(() => {
|
|
3538
4044
|
const ctrl = new AbortController();
|
|
3539
4045
|
void client.ready.then(
|
|
3540
4046
|
() => client.api()?.messengerLook(ctrl.signal).then(setLook).catch(() => void 0)
|
|
@@ -3562,9 +4068,9 @@ var MRRocketMessenger = ({ client, appearance, options: given = {} }) => {
|
|
|
3562
4068
|
const p = usePalette({ theme: appearance?.theme ?? look?.theme, accent: appearance?.accent ?? look?.accent });
|
|
3563
4069
|
const k = kit(p);
|
|
3564
4070
|
const open = messengerOpen.useOpen();
|
|
3565
|
-
const [view, setViewState] = (0,
|
|
3566
|
-
const [banner, setBanner] = (0,
|
|
3567
|
-
(0,
|
|
4071
|
+
const [view, setViewState] = (0, import_react3.useState)(msgView);
|
|
4072
|
+
const [banner, setBanner] = (0, import_react3.useState)(null);
|
|
4073
|
+
(0, import_react3.useEffect)(() => {
|
|
3568
4074
|
if (open) setViewState(msgView);
|
|
3569
4075
|
}, [open]);
|
|
3570
4076
|
const setView = (v) => {
|
|
@@ -3573,13 +4079,13 @@ var MRRocketMessenger = ({ client, appearance, options: given = {} }) => {
|
|
|
3573
4079
|
};
|
|
3574
4080
|
const chat = useChat(client, options, open, view);
|
|
3575
4081
|
const latest = chat.unseen.at(-1);
|
|
3576
|
-
(0,
|
|
4082
|
+
(0, import_react3.useEffect)(() => {
|
|
3577
4083
|
if (!latest || open || options.preview === false) return;
|
|
3578
4084
|
setBanner(latest);
|
|
3579
4085
|
const t = setTimeout(() => setBanner(null), 6e3);
|
|
3580
4086
|
return () => clearTimeout(t);
|
|
3581
4087
|
}, [latest, open, options.preview]);
|
|
3582
|
-
(0,
|
|
4088
|
+
(0, import_react3.useEffect)(() => {
|
|
3583
4089
|
if (open) setBanner(null);
|
|
3584
4090
|
}, [open]);
|
|
3585
4091
|
const unseen = chat.unseen.length;
|
|
@@ -3591,10 +4097,10 @@ var MRRocketMessenger = ({ client, appearance, options: given = {} }) => {
|
|
|
3591
4097
|
...edge === "top" ? { top: 60 } : edge === "bottom" ? { bottom: 34 } : { top: 0, bottom: 0, justifyContent: "center" },
|
|
3592
4098
|
...side === "left" ? { left: 20 } : side === "right" ? { right: 20 } : { left: 0, right: 0, alignItems: "center" }
|
|
3593
4099
|
};
|
|
3594
|
-
const launcher = options.launcher ? (0,
|
|
4100
|
+
const launcher = options.launcher ? (0, import_react3.createElement)(
|
|
3595
4101
|
RN3.View,
|
|
3596
4102
|
{ key: "launcher", pointerEvents: "box-none", style: { position: "absolute", ...place } },
|
|
3597
|
-
(0,
|
|
4103
|
+
(0, import_react3.createElement)(
|
|
3598
4104
|
RN3.Pressable,
|
|
3599
4105
|
{
|
|
3600
4106
|
onPress: () => openAt(unseen ? "messages" : "home"),
|
|
@@ -3619,10 +4125,10 @@ var MRRocketMessenger = ({ client, appearance, options: given = {} }) => {
|
|
|
3619
4125
|
},
|
|
3620
4126
|
glyph("chat", ink, label ? 20 : 26),
|
|
3621
4127
|
label ? k.text(label, { color: ink, fontWeight: "700" }) : null,
|
|
3622
|
-
unseen ? (0,
|
|
4128
|
+
unseen ? (0, import_react3.createElement)(RN3.View, { style: { position: "absolute", top: -2, right: -2, minWidth: 20, height: 20, borderRadius: 10, backgroundColor: p.danger, alignItems: "center", justifyContent: "center", borderWidth: 2, borderColor: p.bg } }, k.text(String(Math.min(unseen, 9)), { color: "#fff", fontSize: 11, fontWeight: "700" })) : null
|
|
3623
4129
|
)
|
|
3624
4130
|
) : null;
|
|
3625
|
-
const toast = banner ? (0,
|
|
4131
|
+
const toast = banner ? (0, import_react3.createElement)(
|
|
3626
4132
|
RN3.Pressable,
|
|
3627
4133
|
{
|
|
3628
4134
|
key: "banner",
|
|
@@ -3647,29 +4153,29 @@ var MRRocketMessenger = ({ client, appearance, options: given = {} }) => {
|
|
|
3647
4153
|
}
|
|
3648
4154
|
},
|
|
3649
4155
|
k.muted(`${who(banner.from, options.agentName)}${unseen > 1 ? ` \xB7 ${unseen} new` : ""}`, { fontWeight: "600", fontSize: 12 }),
|
|
3650
|
-
(0,
|
|
4156
|
+
(0, import_react3.createElement)(RN3.Text, { numberOfLines: 3, style: { color: p.fg, fontSize: 15, lineHeight: 20 } }, banner.body)
|
|
3651
4157
|
) : null;
|
|
3652
4158
|
if (!launcher && !toast && !open) return null;
|
|
3653
|
-
return (0,
|
|
4159
|
+
return (0, import_react3.createElement)(
|
|
3654
4160
|
RN3.View,
|
|
3655
4161
|
{ pointerEvents: "box-none", style: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0 } },
|
|
3656
4162
|
launcher,
|
|
3657
4163
|
toast,
|
|
3658
|
-
open ? (0,
|
|
4164
|
+
open ? (0, import_react3.createElement)(MessengerSheet, { client, p, o: options, chat, view, setView, brand: look?.branding !== false }) : null
|
|
3659
4165
|
);
|
|
3660
4166
|
};
|
|
3661
4167
|
|
|
3662
4168
|
// src/native/index.tsx
|
|
3663
4169
|
var RN4 = require("react-native");
|
|
3664
4170
|
var MRRocketMask = ({ children, style }) => {
|
|
3665
|
-
const ref = (0,
|
|
3666
|
-
(0,
|
|
4171
|
+
const ref = (0, import_react4.useRef)(null);
|
|
4172
|
+
(0, import_react4.useEffect)(() => {
|
|
3667
4173
|
maskedViews.add(ref);
|
|
3668
4174
|
return () => {
|
|
3669
4175
|
maskedViews.delete(ref);
|
|
3670
4176
|
};
|
|
3671
4177
|
}, []);
|
|
3672
|
-
return (0,
|
|
4178
|
+
return (0, import_react4.createElement)(RN4.View, { ref, collapsable: false, style }, children);
|
|
3673
4179
|
};
|
|
3674
4180
|
var shared = null;
|
|
3675
4181
|
var sharedKey = "";
|
|
@@ -3686,16 +4192,16 @@ var createMRRocket = (options) => {
|
|
|
3686
4192
|
return shared;
|
|
3687
4193
|
};
|
|
3688
4194
|
var getMRRocket = () => shared;
|
|
3689
|
-
var Ctx = (0,
|
|
4195
|
+
var Ctx = (0, import_react4.createContext)(null);
|
|
3690
4196
|
var MRRocketProvider = ({ client: given, children, consent, flows = true, appearance, surveys = true, messenger = {}, feedback = {}, heatmaps = true, ...options }) => {
|
|
3691
|
-
const [client] = (0,
|
|
3692
|
-
(0,
|
|
4197
|
+
const [client] = (0, import_react4.useState)(() => given ?? createMRRocket({ ...options, consent }));
|
|
4198
|
+
(0, import_react4.useEffect)(() => {
|
|
3693
4199
|
if (consent) client.setConsent(consent);
|
|
3694
4200
|
}, [client, consent]);
|
|
3695
|
-
(0,
|
|
4201
|
+
(0, import_react4.useEffect)(() => {
|
|
3696
4202
|
if (options.replay !== void 0) client.setReplay(options.replay);
|
|
3697
4203
|
}, [client, options.replay]);
|
|
3698
|
-
const start = (0,
|
|
4204
|
+
const start = (0, import_react4.useRef)(null);
|
|
3699
4205
|
const touch = (e, end) => {
|
|
3700
4206
|
const n = e.nativeEvent;
|
|
3701
4207
|
const x = n.pageX ?? n.changedTouches?.[0]?.pageX;
|
|
@@ -3704,22 +4210,22 @@ var MRRocketProvider = ({ client: given, children, consent, flows = true, appear
|
|
|
3704
4210
|
if (!end) start.current = { x, y, t: Date.now() };
|
|
3705
4211
|
else if (start.current && Math.hypot(x - start.current.x, y - start.current.y) < 10 && Date.now() - start.current.t < 500) client.tap(x, y);
|
|
3706
4212
|
};
|
|
3707
|
-
return (0,
|
|
4213
|
+
return (0, import_react4.createElement)(
|
|
3708
4214
|
Ctx.Provider,
|
|
3709
4215
|
{ value: client },
|
|
3710
|
-
heatmaps ? (0,
|
|
3711
|
-
flows ? (0,
|
|
3712
|
-
surveys ? (0,
|
|
3713
|
-
feedback ? (0,
|
|
3714
|
-
messenger ? (0,
|
|
4216
|
+
heatmaps ? (0, import_react4.createElement)(RN4.View, { style: { flex: 1 }, onTouchStartCapture: (e) => touch(e, false), onTouchEndCapture: (e) => touch(e, true) }, children) : children,
|
|
4217
|
+
flows ? (0, import_react4.createElement)(MRRocketFlows, { flows: client.flows, paywall: client.paywall, appearance }) : null,
|
|
4218
|
+
surveys ? (0, import_react4.createElement)(MRRocketSurveys, { client, appearance }) : null,
|
|
4219
|
+
feedback ? (0, import_react4.createElement)(MRRocketFeedback, { client, appearance, options: feedback }) : null,
|
|
4220
|
+
messenger ? (0, import_react4.createElement)(MRRocketMessenger, { client, appearance, options: messenger }) : null
|
|
3715
4221
|
);
|
|
3716
4222
|
};
|
|
3717
4223
|
var useClient = () => {
|
|
3718
|
-
const c = (0,
|
|
4224
|
+
const c = (0, import_react4.useContext)(Ctx);
|
|
3719
4225
|
if (!c) throw new Error("MRRocket: wrap your app in <MRRocketProvider apiKey=\u2026>.");
|
|
3720
4226
|
return c;
|
|
3721
4227
|
};
|
|
3722
|
-
var useVersion = (client) => (0,
|
|
4228
|
+
var useVersion = (client) => (0, import_react4.useSyncExternalStore)(client.subscribe, client.getVersion, client.getVersion);
|
|
3723
4229
|
var useMRRocket = () => {
|
|
3724
4230
|
const client = useClient();
|
|
3725
4231
|
useVersion(client);
|
|
@@ -3753,9 +4259,9 @@ var useReview = () => {
|
|
|
3753
4259
|
const client = useClient();
|
|
3754
4260
|
return { request: client.requestReview };
|
|
3755
4261
|
};
|
|
3756
|
-
var useOnboarding = () => {
|
|
4262
|
+
var useOnboarding = (id) => {
|
|
3757
4263
|
const client = useClient();
|
|
3758
|
-
return
|
|
4264
|
+
return useOnboardingItem(client.flows, id, client.startOnboarding);
|
|
3759
4265
|
};
|
|
3760
4266
|
var useFlag = (key) => {
|
|
3761
4267
|
const client = useClient();
|
|
@@ -3772,7 +4278,7 @@ var useVariant = (key) => {
|
|
|
3772
4278
|
useVersion(client);
|
|
3773
4279
|
const config = client.getConfig();
|
|
3774
4280
|
const variant = client.peekVariant(key);
|
|
3775
|
-
(0,
|
|
4281
|
+
(0, import_react4.useEffect)(() => {
|
|
3776
4282
|
if (config) client.expose(key, variant);
|
|
3777
4283
|
}, [client, config, key, variant]);
|
|
3778
4284
|
return variant;
|
|
@@ -3783,7 +4289,7 @@ var useText = (id, fallback) => {
|
|
|
3783
4289
|
const config = client.getConfig();
|
|
3784
4290
|
const text2 = client.peekText(id);
|
|
3785
4291
|
const person = client.getDistinctId();
|
|
3786
|
-
(0,
|
|
4292
|
+
(0, import_react4.useEffect)(() => {
|
|
3787
4293
|
if (config) client.exposeText(id);
|
|
3788
4294
|
}, [client, config, id, person]);
|
|
3789
4295
|
return text2 ?? fallback;
|
|
@@ -3808,13 +4314,13 @@ var useExpoRouterTracking = () => {
|
|
|
3808
4314
|
console.warn("[MRRocket] useExpoRouterTracking needs expo-router. With React Navigation use useNavigationTracking.");
|
|
3809
4315
|
}
|
|
3810
4316
|
const pathname = (router?.usePathname ?? noPathname)();
|
|
3811
|
-
(0,
|
|
4317
|
+
(0, import_react4.useEffect)(() => {
|
|
3812
4318
|
if (pathname) client.screen(pathname);
|
|
3813
4319
|
}, [client, pathname]);
|
|
3814
4320
|
};
|
|
3815
4321
|
var useNavigationTracking = () => {
|
|
3816
4322
|
const client = useClient();
|
|
3817
|
-
return (0,
|
|
4323
|
+
return (0, import_react4.useCallback)(
|
|
3818
4324
|
(state) => {
|
|
3819
4325
|
const name = activeRouteName(state);
|
|
3820
4326
|
if (name) client.screen(name);
|