@guidelytech/react-native 0.4.1 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +385 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +481 -156
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -54,7 +54,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
54
54
|
var import_react8 = require("react");
|
|
55
55
|
var import_react_native11 = require("react-native");
|
|
56
56
|
|
|
57
|
-
// ../shared/dist/chunk-
|
|
57
|
+
// ../shared/dist/chunk-OLWGMDRX.js
|
|
58
58
|
function fnv1a(input) {
|
|
59
59
|
let h = 2166136261;
|
|
60
60
|
for (let i = 0; i < input.length; i++) {
|
|
@@ -358,8 +358,194 @@ function sanitizeProperties(props) {
|
|
|
358
358
|
return out;
|
|
359
359
|
}
|
|
360
360
|
var SOURCEMAP_MAX_FILE_BYTES = 25 * 1024 * 1024;
|
|
361
|
+
var MEDIA_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
|
|
362
|
+
var MEDIA_VIDEO_MAX_BYTES = 200 * 1024 * 1024;
|
|
363
|
+
var MEDIA_FILE_MAX_BYTES = 50 * 1024 * 1024;
|
|
364
|
+
var MEDIA_MAX_BYTES = Math.max(MEDIA_IMAGE_MAX_BYTES, MEDIA_VIDEO_MAX_BYTES, MEDIA_FILE_MAX_BYTES);
|
|
365
|
+
var FILE_LINK_CLASS = "gd-file";
|
|
366
|
+
var PDF_BLOCK_CLASS = "gd-pdf";
|
|
367
|
+
function isFileLink(className, href) {
|
|
368
|
+
return !!className && className.split(/\s+/).includes(FILE_LINK_CLASS) && isSafeMediaUrl(href);
|
|
369
|
+
}
|
|
370
|
+
var YOUTUBE_ID = /^[A-Za-z0-9_-]{11}$/;
|
|
371
|
+
var VIMEO_ID = /^\d{1,12}$/;
|
|
372
|
+
var VIMEO_HASH = /^[0-9a-f]{6,20}$/i;
|
|
373
|
+
var LOOM_ID = /^[0-9a-f]{32}$/i;
|
|
374
|
+
var WISTIA_ID = /^[a-z0-9]{10}$/i;
|
|
375
|
+
function parseUrl(input) {
|
|
376
|
+
const s = input.trim();
|
|
377
|
+
if (!s) return null;
|
|
378
|
+
try {
|
|
379
|
+
const u = new URL(/^[a-z][a-z0-9+.-]*:/i.test(s) ? s : `https://${s}`);
|
|
380
|
+
if (u.protocol !== "https:" && u.protocol !== "http:") return null;
|
|
381
|
+
if (u.username || u.password || u.port && u.port !== "443" && u.port !== "80") return null;
|
|
382
|
+
return u;
|
|
383
|
+
} catch {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function parseStart(v) {
|
|
388
|
+
if (!v) return 0;
|
|
389
|
+
if (/^\d+$/.test(v)) return Math.min(Number(v), 86400);
|
|
390
|
+
const m = /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$/.exec(v);
|
|
391
|
+
if (!m || !m[0]) return 0;
|
|
392
|
+
return Math.min(Number(m[1] ?? 0) * 3600 + Number(m[2] ?? 0) * 60 + Number(m[3] ?? 0), 86400);
|
|
393
|
+
}
|
|
394
|
+
function youtube(id, start) {
|
|
395
|
+
if (!YOUTUBE_ID.test(id)) return null;
|
|
396
|
+
return {
|
|
397
|
+
provider: "youtube",
|
|
398
|
+
src: `https://www.youtube-nocookie.com/embed/${id}${start ? `?start=${start}` : ""}`,
|
|
399
|
+
watchUrl: `https://www.youtube.com/watch?v=${id}${start ? `&t=${start}s` : ""}`,
|
|
400
|
+
title: "YouTube video"
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
function vimeo(id, hash) {
|
|
404
|
+
if (!VIMEO_ID.test(id) || hash !== null && !VIMEO_HASH.test(hash)) return null;
|
|
405
|
+
const h = hash ? hash.toLowerCase() : null;
|
|
406
|
+
return { provider: "vimeo", src: `https://player.vimeo.com/video/${id}${h ? `?h=${h}` : ""}`, watchUrl: `https://vimeo.com/${id}${h ? `/${h}` : ""}`, title: "Vimeo video" };
|
|
407
|
+
}
|
|
408
|
+
function toEmbedUrl(input) {
|
|
409
|
+
const u = parseUrl(input);
|
|
410
|
+
if (!u) return null;
|
|
411
|
+
const host = u.hostname.toLowerCase().replace(/^www\./, "");
|
|
412
|
+
const parts = u.pathname.split("/").filter(Boolean);
|
|
413
|
+
switch (host) {
|
|
414
|
+
case "youtube.com":
|
|
415
|
+
case "m.youtube.com":
|
|
416
|
+
case "youtube-nocookie.com": {
|
|
417
|
+
const start = parseStart(u.searchParams.get("start") ?? u.searchParams.get("t"));
|
|
418
|
+
if (parts[0] === "watch" && parts.length === 1) return youtube(u.searchParams.get("v") ?? "", start);
|
|
419
|
+
if ((parts[0] === "embed" || parts[0] === "shorts" || parts[0] === "live") && parts.length === 2) return youtube(parts[1], start);
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
case "youtu.be":
|
|
423
|
+
return parts.length === 1 ? youtube(parts[0], parseStart(u.searchParams.get("t") ?? u.searchParams.get("start"))) : null;
|
|
424
|
+
case "vimeo.com":
|
|
425
|
+
if (parts.length === 1) return vimeo(parts[0], null);
|
|
426
|
+
if (parts.length === 2 && VIMEO_ID.test(parts[0])) return vimeo(parts[0], parts[1]);
|
|
427
|
+
return null;
|
|
428
|
+
case "player.vimeo.com":
|
|
429
|
+
return parts[0] === "video" && parts.length === 2 ? vimeo(parts[1], u.searchParams.get("h")) : null;
|
|
430
|
+
case "loom.com":
|
|
431
|
+
if ((parts[0] === "share" || parts[0] === "embed") && parts.length === 2 && LOOM_ID.test(parts[1])) {
|
|
432
|
+
const id = parts[1].toLowerCase();
|
|
433
|
+
return { provider: "loom", src: `https://www.loom.com/embed/${id}`, watchUrl: `https://www.loom.com/share/${id}`, title: "Loom video" };
|
|
434
|
+
}
|
|
435
|
+
return null;
|
|
436
|
+
default: {
|
|
437
|
+
let id;
|
|
438
|
+
if (host === "fast.wistia.net" || host === "fast.wistia.com") id = parts[0] === "embed" && parts[1] === "iframe" && parts.length === 3 ? parts[2] : void 0;
|
|
439
|
+
else if (host === "wi.st" || host === "wistia.com" || /^[a-z0-9-]+\.wistia\.com$/.test(host)) id = parts[0] === "medias" && parts.length === 2 ? parts[1] : void 0;
|
|
440
|
+
if (!id || !WISTIA_ID.test(id)) return null;
|
|
441
|
+
return { provider: "wistia", src: `https://fast.wistia.net/embed/iframe/${id}`, watchUrl: `https://fast.wistia.net/embed/iframe/${id}`, title: "Wistia video" };
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function isAllowedEmbedSrc(src) {
|
|
446
|
+
if (!src) return false;
|
|
447
|
+
return toEmbedUrl(src)?.src === src;
|
|
448
|
+
}
|
|
449
|
+
function isSafeMediaUrl(url) {
|
|
450
|
+
if (!url) return false;
|
|
451
|
+
try {
|
|
452
|
+
const u = new URL(url);
|
|
453
|
+
return (u.protocol === "https:" || u.protocol === "http:") && !u.username && !u.password;
|
|
454
|
+
} catch {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
var MAX_COLLECTION_DEPTH = 3;
|
|
459
|
+
function matchesAudiences(required, member) {
|
|
460
|
+
if (!required || required.length === 0) return true;
|
|
461
|
+
if (!member) return false;
|
|
462
|
+
const has2 = member instanceof Set ? (id) => member.has(id) : (id) => member.includes(id);
|
|
463
|
+
return required.some(has2);
|
|
464
|
+
}
|
|
465
|
+
function resourceCenterSections(collections, articles, member) {
|
|
466
|
+
const byId = new Map(collections.map((c) => [c.id, c]));
|
|
467
|
+
const children = /* @__PURE__ */ new Map();
|
|
468
|
+
for (const c of collections) {
|
|
469
|
+
const parent = c.parentId && c.parentId !== c.id && byId.has(c.parentId) ? c.parentId : null;
|
|
470
|
+
const list = children.get(parent) ?? [];
|
|
471
|
+
list.push(c);
|
|
472
|
+
children.set(parent, list);
|
|
473
|
+
}
|
|
474
|
+
for (const list of children.values()) list.sort((a, b) => a.order - b.order || a.name.localeCompare(b.name));
|
|
475
|
+
const direct = /* @__PURE__ */ new Map();
|
|
476
|
+
const uncategorized = [];
|
|
477
|
+
for (const a of articles) {
|
|
478
|
+
if (!matchesAudiences(a.audienceIds, member)) continue;
|
|
479
|
+
if (a.collectionId && byId.has(a.collectionId)) {
|
|
480
|
+
const list = direct.get(a.collectionId) ?? [];
|
|
481
|
+
list.push(a);
|
|
482
|
+
direct.set(a.collectionId, list);
|
|
483
|
+
} else uncategorized.push(a);
|
|
484
|
+
}
|
|
485
|
+
const sections = [];
|
|
486
|
+
const seen = /* @__PURE__ */ new Set();
|
|
487
|
+
const visit = (c, path) => {
|
|
488
|
+
if (seen.has(c.id)) return;
|
|
489
|
+
seen.add(c.id);
|
|
490
|
+
if (!matchesAudiences(c.audienceIds, member)) return;
|
|
491
|
+
const here = [...path, c.name];
|
|
492
|
+
const list = direct.get(c.id);
|
|
493
|
+
if (list?.length) sections.push({ collection: c, path: here, depth: here.length - 1, articles: list });
|
|
494
|
+
for (const child of children.get(c.id) ?? []) visit(child, here);
|
|
495
|
+
};
|
|
496
|
+
for (const root of children.get(null) ?? []) visit(root, []);
|
|
497
|
+
if (uncategorized.length) sections.push({ collection: null, path: [], depth: 0, articles: uncategorized });
|
|
498
|
+
return sections;
|
|
499
|
+
}
|
|
500
|
+
function isArticleListed(collections, article, member) {
|
|
501
|
+
if (!matchesAudiences(article.audienceIds, member)) return false;
|
|
502
|
+
const byId = new Map(collections.map((c) => [c.id, c]));
|
|
503
|
+
let cur = article.collectionId ? byId.get(article.collectionId) : void 0;
|
|
504
|
+
for (let guard = 0; cur && guard <= MAX_COLLECTION_DEPTH * 4; guard++) {
|
|
505
|
+
if (!matchesAudiences(cur.audienceIds, member)) return false;
|
|
506
|
+
cur = cur.parentId ? byId.get(cur.parentId) : void 0;
|
|
507
|
+
}
|
|
508
|
+
return true;
|
|
509
|
+
}
|
|
510
|
+
var CAPTURE_SCREENSHOT_MAX_BYTES = 8 * 1024 * 1024;
|
|
361
511
|
|
|
362
|
-
// ../sdk-core/dist/chunk-
|
|
512
|
+
// ../sdk-core/dist/chunk-CYAG6ZYX.js
|
|
513
|
+
function readJson(store, key, fallback) {
|
|
514
|
+
const raw = store.get(key);
|
|
515
|
+
if (raw == null) return fallback;
|
|
516
|
+
try {
|
|
517
|
+
return JSON.parse(raw);
|
|
518
|
+
} catch {
|
|
519
|
+
return fallback;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
function writeJson(store, key, value) {
|
|
523
|
+
try {
|
|
524
|
+
store.set(key, JSON.stringify(value));
|
|
525
|
+
} catch {
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
var KEYS = {
|
|
529
|
+
anon: "guidely:anon",
|
|
530
|
+
seen: "guidely:seen",
|
|
531
|
+
config: (key) => `guidely:config:${key}`,
|
|
532
|
+
etag: (key) => `guidely:etag:${key}`,
|
|
533
|
+
state: (key) => `guidely:state:${key}`,
|
|
534
|
+
user: (key) => `guidely:user:${key}`,
|
|
535
|
+
queue: (key) => `guidely:queue:${key}`,
|
|
536
|
+
session: "guidely:session",
|
|
537
|
+
active: "guidely:active",
|
|
538
|
+
authoring: "guidely:authoring",
|
|
539
|
+
/** How-to capture session marker ({ token, … }) and its not-yet-uploaded steps. */
|
|
540
|
+
capture: "guidely:capture",
|
|
541
|
+
capturePending: "guidely:capture:pending",
|
|
542
|
+
/** Messenger conversations this browser can read: [{ id, token }]. */
|
|
543
|
+
conversations: (key) => `guidely:conversations:${key}`,
|
|
544
|
+
/** Announcement ids opened in the messenger's News tab. */
|
|
545
|
+
newsSeen: (key) => `guidely:news:${key}`
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
// ../sdk-core/dist/chunk-AKNE7D5M.js
|
|
363
549
|
var __defProp2 = Object.defineProperty;
|
|
364
550
|
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
365
551
|
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -381,7 +567,8 @@ var Api = class {
|
|
|
381
567
|
const f = this.fetcher;
|
|
382
568
|
if (!f) throw new Error("fetch is not available");
|
|
383
569
|
const headers = { ...options.headers, "X-Guidely-Key": this.key, Accept: "application/json" };
|
|
384
|
-
|
|
570
|
+
const form = typeof FormData !== "undefined" && options.body instanceof FormData;
|
|
571
|
+
if (options.body !== void 0 && !form) headers["Content-Type"] = "application/json";
|
|
385
572
|
if (options.etag) headers["If-None-Match"] = options.etag;
|
|
386
573
|
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
387
574
|
const timer = ac ? setTimeout(() => ac.abort(), options.timeoutMs ?? 1e4) : null;
|
|
@@ -389,7 +576,7 @@ var Api = class {
|
|
|
389
576
|
const res = await f(this.url(path, options.params), {
|
|
390
577
|
method,
|
|
391
578
|
headers,
|
|
392
|
-
body: options.body === void 0 ? void 0 : JSON.stringify(options.body),
|
|
579
|
+
body: options.body === void 0 ? void 0 : form ? options.body : JSON.stringify(options.body),
|
|
393
580
|
keepalive: options.keepalive,
|
|
394
581
|
signal: ac?.signal,
|
|
395
582
|
credentials: "omit",
|
|
@@ -414,6 +601,10 @@ var Api = class {
|
|
|
414
601
|
post(path, body, options) {
|
|
415
602
|
return this.request("POST", path, { body, ...options });
|
|
416
603
|
}
|
|
604
|
+
/** Multipart POST (file uploads). No Content-Type header: the browser adds it with the boundary. */
|
|
605
|
+
postForm(path, form, options) {
|
|
606
|
+
return this.request("POST", path, { body: form, ...options });
|
|
607
|
+
}
|
|
417
608
|
/**
|
|
418
609
|
* POST that may answer with server-sent events. Each event is passed to `onEvent`; a JSON answer is
|
|
419
610
|
* returned instead. No timeout: Scout replies can take a while and the server keeps the stream alive.
|
|
@@ -456,10 +647,10 @@ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
456
647
|
function backoffMs(attempt, baseMs = 1e3, maxMs = 3e4) {
|
|
457
648
|
return Math.min(maxMs, baseMs * 2 ** Math.max(0, attempt));
|
|
458
649
|
}
|
|
459
|
-
async function
|
|
650
|
+
async function withRetry(send, attempts = 3, baseMs = 500) {
|
|
460
651
|
for (let i = 0; i < attempts; i++) {
|
|
461
652
|
try {
|
|
462
|
-
const res = await
|
|
653
|
+
const res = await send();
|
|
463
654
|
if (res.ok || res.status >= 400 && res.status < 500 && res.status !== 429) return res;
|
|
464
655
|
} catch {
|
|
465
656
|
}
|
|
@@ -467,6 +658,9 @@ async function postWithRetry(api, path, body, attempts = 3, baseMs = 500) {
|
|
|
467
658
|
}
|
|
468
659
|
return null;
|
|
469
660
|
}
|
|
661
|
+
function postWithRetry(api, path, body, attempts = 3, baseMs = 500) {
|
|
662
|
+
return withRetry(() => api.post(path, body), attempts, baseMs);
|
|
663
|
+
}
|
|
470
664
|
async function readEventStream(body, onEvent) {
|
|
471
665
|
const reader = body.getReader();
|
|
472
666
|
const decoder = new TextDecoder();
|
|
@@ -501,36 +695,7 @@ async function readEventStream(body, onEvent) {
|
|
|
501
695
|
if (buffer.trim()) dispatch(buffer);
|
|
502
696
|
}
|
|
503
697
|
|
|
504
|
-
// ../sdk-core/dist/chunk-
|
|
505
|
-
function readJson(store, key, fallback) {
|
|
506
|
-
const raw = store.get(key);
|
|
507
|
-
if (raw == null) return fallback;
|
|
508
|
-
try {
|
|
509
|
-
return JSON.parse(raw);
|
|
510
|
-
} catch {
|
|
511
|
-
return fallback;
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
function writeJson(store, key, value) {
|
|
515
|
-
try {
|
|
516
|
-
store.set(key, JSON.stringify(value));
|
|
517
|
-
} catch {
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
var KEYS = {
|
|
521
|
-
anon: "guidely:anon",
|
|
522
|
-
seen: "guidely:seen",
|
|
523
|
-
config: (key) => `guidely:config:${key}`,
|
|
524
|
-
etag: (key) => `guidely:etag:${key}`,
|
|
525
|
-
state: (key) => `guidely:state:${key}`,
|
|
526
|
-
user: (key) => `guidely:user:${key}`,
|
|
527
|
-
queue: (key) => `guidely:queue:${key}`,
|
|
528
|
-
session: "guidely:session",
|
|
529
|
-
active: "guidely:active",
|
|
530
|
-
authoring: "guidely:authoring",
|
|
531
|
-
/** Messenger conversations this browser can read: [{ id, token }]. */
|
|
532
|
-
conversations: (key) => `guidely:conversations:${key}`
|
|
533
|
-
};
|
|
698
|
+
// ../sdk-core/dist/chunk-GDF6RCHQ.js
|
|
534
699
|
var EventQueue = class {
|
|
535
700
|
constructor(opts) {
|
|
536
701
|
__publicField2(this, "opts", opts);
|
|
@@ -1612,7 +1777,7 @@ var PersistentStore = class {
|
|
|
1612
1777
|
|
|
1613
1778
|
// src/core/client.ts
|
|
1614
1779
|
var SDK_NAME = "@guidelytech/react-native";
|
|
1615
|
-
var SDK_VERSION = "0.
|
|
1780
|
+
var SDK_VERSION = "0.6.1";
|
|
1616
1781
|
var DEFAULT_API_URL = "https://guidelytech.com";
|
|
1617
1782
|
var PAGE_SCOPED = /* @__PURE__ */ new Set(["page_load", "url_match", "element_click", "element_visible", "delay"]);
|
|
1618
1783
|
var nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -2477,6 +2642,10 @@ var GuidelyClient = class {
|
|
|
2477
2642
|
if (this.activeSurvey?.guide.id !== guideId) return;
|
|
2478
2643
|
this.finishSurvey(this.surveyView?.submitted ? "submitted" : "dismissed");
|
|
2479
2644
|
}
|
|
2645
|
+
/** The visitor's audiences (from the last identify), for audience-targeted help articles. */
|
|
2646
|
+
getAudienceIds() {
|
|
2647
|
+
return this.state.audienceIds;
|
|
2648
|
+
}
|
|
2480
2649
|
getResourceCenter() {
|
|
2481
2650
|
const rc = this.config?.resourceCenter;
|
|
2482
2651
|
return rc && rc.enabled ? rc : null;
|
|
@@ -2814,7 +2983,8 @@ function decodeEntities(s) {
|
|
|
2814
2983
|
});
|
|
2815
2984
|
}
|
|
2816
2985
|
var BLOCK_TAGS = /* @__PURE__ */ new Set(["p", "div", "section", "article", "header", "footer", "h1", "h2", "h3", "h4", "h5", "h6", "li", "blockquote", "ul", "ol", "table", "tr", "pre"]);
|
|
2817
|
-
var SKIP_TAGS = /* @__PURE__ */ new Set(["script", "style", "head", "title", "svg", "template"]);
|
|
2986
|
+
var SKIP_TAGS = /* @__PURE__ */ new Set(["script", "style", "head", "title", "svg", "template", "iframe", "video"]);
|
|
2987
|
+
var PROVIDER_LABEL = { youtube: "Watch on YouTube", vimeo: "Watch on Vimeo", loom: "Watch on Loom", wistia: "Watch video" };
|
|
2818
2988
|
function attr(attrs, name) {
|
|
2819
2989
|
const m = attrs.match(new RegExp(`\\b${name}\\s*=\\s*("([^"]*)"|'([^']*)'|([^\\s>]+))`, "i"));
|
|
2820
2990
|
return m ? decodeEntities(m[2] ?? m[3] ?? m[4] ?? "") : void 0;
|
|
@@ -2826,6 +2996,12 @@ function parseHtml(html) {
|
|
|
2826
2996
|
const lists = [];
|
|
2827
2997
|
let current = null;
|
|
2828
2998
|
let skipping = null;
|
|
2999
|
+
let pdf = null;
|
|
3000
|
+
let fileLink = null;
|
|
3001
|
+
const media = (block) => {
|
|
3002
|
+
flush();
|
|
3003
|
+
blocks.push({ level: 1, runs: [], ...block });
|
|
3004
|
+
};
|
|
2829
3005
|
const flush = () => {
|
|
2830
3006
|
if (current) {
|
|
2831
3007
|
const runs = current.runs;
|
|
@@ -2856,12 +3032,30 @@ function parseHtml(html) {
|
|
|
2856
3032
|
if (last && last.bold === run.bold && last.italic === run.italic && last.underline === run.underline && last.code === run.code && last.href === run.href) last.text += text;
|
|
2857
3033
|
else current.runs.push(run);
|
|
2858
3034
|
};
|
|
3035
|
+
const size = (attrs, name) => {
|
|
3036
|
+
const n = Number(attr(attrs, name));
|
|
3037
|
+
return n > 0 ? n : void 0;
|
|
3038
|
+
};
|
|
3039
|
+
const endPdf = (p) => {
|
|
3040
|
+
const name = p.name.replace(/\s+/g, " ").trim();
|
|
3041
|
+
if (p.href && p.pages.length) media({ kind: "pdf", href: p.href, alt: name || "PDF", pages: p.pages });
|
|
3042
|
+
else if (p.href) media({ kind: "file", href: p.href, alt: name || "Open PDF" });
|
|
3043
|
+
else for (const page of p.pages) media({ kind: "image", src: page.src, alt: page.alt, ...page.width && page.height ? { width: page.width, height: page.height } : {} });
|
|
3044
|
+
};
|
|
2859
3045
|
const re = /<!--[\s\S]*?-->|<\/?([a-zA-Z][a-zA-Z0-9]*)\b([^>]*)>|([^<]+|<)/g;
|
|
2860
3046
|
let m;
|
|
2861
3047
|
while (m = re.exec(html || "")) {
|
|
2862
3048
|
const [token, rawTag, attrs = "", text] = m;
|
|
2863
3049
|
if (text !== void 0) {
|
|
2864
3050
|
if (skipping) continue;
|
|
3051
|
+
if (pdf) {
|
|
3052
|
+
if (pdf.inLink) pdf.name += decodeEntities(text);
|
|
3053
|
+
continue;
|
|
3054
|
+
}
|
|
3055
|
+
if (fileLink) {
|
|
3056
|
+
fileLink.name += decodeEntities(text);
|
|
3057
|
+
continue;
|
|
3058
|
+
}
|
|
2865
3059
|
push(decodeEntities(text.replace(/\s+/g, " ")));
|
|
2866
3060
|
continue;
|
|
2867
3061
|
}
|
|
@@ -2873,7 +3067,54 @@ function parseHtml(html) {
|
|
|
2873
3067
|
continue;
|
|
2874
3068
|
}
|
|
2875
3069
|
if (SKIP_TAGS.has(tag)) {
|
|
2876
|
-
if (
|
|
3070
|
+
if (closing) continue;
|
|
3071
|
+
if (tag === "iframe") {
|
|
3072
|
+
const src = attr(attrs, "src");
|
|
3073
|
+
const embed = isAllowedEmbedSrc(src) ? toEmbedUrl(src) : null;
|
|
3074
|
+
if (embed) media({ kind: "video", href: embed.watchUrl, alt: PROVIDER_LABEL[embed.provider] });
|
|
3075
|
+
} else if (tag === "video") {
|
|
3076
|
+
const src = attr(attrs, "src");
|
|
3077
|
+
if (isSafeMediaUrl(src)) media({ kind: "video", href: src, alt: "Play video" });
|
|
3078
|
+
}
|
|
3079
|
+
if (!token.endsWith("/>")) skipping = tag;
|
|
3080
|
+
continue;
|
|
3081
|
+
}
|
|
3082
|
+
if (pdf) {
|
|
3083
|
+
if (tag === "div") {
|
|
3084
|
+
pdf.depth += closing ? -1 : 1;
|
|
3085
|
+
if (pdf.depth === 0) {
|
|
3086
|
+
endPdf(pdf);
|
|
3087
|
+
pdf = null;
|
|
3088
|
+
}
|
|
3089
|
+
} else if (tag === "a") {
|
|
3090
|
+
if (closing) pdf.inLink = false;
|
|
3091
|
+
else if (!pdf.href && isFileLink(attr(attrs, "class"), attr(attrs, "href"))) {
|
|
3092
|
+
pdf.href = attr(attrs, "href");
|
|
3093
|
+
pdf.inLink = true;
|
|
3094
|
+
}
|
|
3095
|
+
} else if (tag === "img" && !closing) {
|
|
3096
|
+
const src = attr(attrs, "src");
|
|
3097
|
+
const w = size(attrs, "width");
|
|
3098
|
+
const h = size(attrs, "height");
|
|
3099
|
+
if (isSafeMediaUrl(src)) pdf.pages.push({ src, alt: attr(attrs, "alt") ?? "", ...w && h ? { width: w, height: h } : {} });
|
|
3100
|
+
}
|
|
3101
|
+
continue;
|
|
3102
|
+
}
|
|
3103
|
+
if (fileLink) {
|
|
3104
|
+
if (closing && tag === "a") {
|
|
3105
|
+
media({ kind: "file", href: fileLink.href, alt: fileLink.name.replace(/\s+/g, " ").trim() || "Open PDF" });
|
|
3106
|
+
fileLink = null;
|
|
3107
|
+
}
|
|
3108
|
+
continue;
|
|
3109
|
+
}
|
|
3110
|
+
if (!closing && tag === "div" && (attr(attrs, "class") ?? "").split(/\s+/).includes(PDF_BLOCK_CLASS)) {
|
|
3111
|
+
flush();
|
|
3112
|
+
pdf = { depth: 1, name: "", inLink: false, pages: [] };
|
|
3113
|
+
continue;
|
|
3114
|
+
}
|
|
3115
|
+
if (!closing && tag === "a" && isFileLink(attr(attrs, "class"), attr(attrs, "href"))) {
|
|
3116
|
+
flush();
|
|
3117
|
+
fileLink = { href: attr(attrs, "href"), name: "" };
|
|
2877
3118
|
continue;
|
|
2878
3119
|
}
|
|
2879
3120
|
if (closing) {
|
|
@@ -2934,16 +3175,23 @@ function parseHtml(html) {
|
|
|
2934
3175
|
default:
|
|
2935
3176
|
if (BLOCK_TAGS.has(tag)) open("paragraph");
|
|
2936
3177
|
else if (tag === "img") {
|
|
2937
|
-
const
|
|
2938
|
-
|
|
3178
|
+
const src = attr(attrs, "src") ?? "";
|
|
3179
|
+
const alt = attr(attrs, "alt") ?? "";
|
|
3180
|
+
if (isSafeMediaUrl(src) || /^data:image\//i.test(src)) {
|
|
3181
|
+
const w = Number(attr(attrs, "width"));
|
|
3182
|
+
const h = Number(attr(attrs, "height"));
|
|
3183
|
+
media({ kind: "image", src, alt, ...w > 0 && h > 0 ? { width: w, height: h } : {} });
|
|
3184
|
+
} else if (alt) push(alt);
|
|
2939
3185
|
}
|
|
2940
3186
|
}
|
|
2941
3187
|
}
|
|
3188
|
+
if (pdf) endPdf(pdf);
|
|
3189
|
+
if (fileLink) media({ kind: "file", href: fileLink.href, alt: fileLink.name.replace(/\s+/g, " ").trim() || "Open PDF" });
|
|
2942
3190
|
flush();
|
|
2943
3191
|
return blocks;
|
|
2944
3192
|
}
|
|
2945
3193
|
function htmlToText(html) {
|
|
2946
|
-
return parseHtml(html).map((b) => (b.marker ? `${b.marker} ` : "") + b.runs.map((r) => r.text).join("")).join("\n");
|
|
3194
|
+
return parseHtml(html).map((b) => b.kind === "image" || b.kind === "video" || b.kind === "pdf" || b.kind === "file" ? b.alt ?? "" : (b.marker ? `${b.marker} ` : "") + b.runs.map((r) => r.text).join("")).filter(Boolean).join("\n");
|
|
2947
3195
|
}
|
|
2948
3196
|
|
|
2949
3197
|
// src/ui/RichText.tsx
|
|
@@ -2960,11 +3208,76 @@ function runStyle(run, p) {
|
|
|
2960
3208
|
color: run.href ? p.primary : void 0
|
|
2961
3209
|
};
|
|
2962
3210
|
}
|
|
3211
|
+
function BodyImage({ block, palette: p }) {
|
|
3212
|
+
const [ratio, setRatio] = (0, import_react.useState)(block.width && block.height ? block.width / block.height : 16 / 9);
|
|
3213
|
+
(0, import_react.useEffect)(() => {
|
|
3214
|
+
if (block.width && block.height) return;
|
|
3215
|
+
let live = true;
|
|
3216
|
+
import_react_native2.Image.getSize(block.src, (w, h) => live && w > 0 && h > 0 && setRatio(w / h), () => {
|
|
3217
|
+
});
|
|
3218
|
+
return () => {
|
|
3219
|
+
live = false;
|
|
3220
|
+
};
|
|
3221
|
+
}, [block.src, block.width, block.height]);
|
|
3222
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: block.src }, accessible: true, accessibilityRole: "image", accessibilityLabel: block.alt || void 0, resizeMode: "contain", style: [styles2.image, { aspectRatio: ratio, backgroundColor: p.surface }] });
|
|
3223
|
+
}
|
|
3224
|
+
function BodyVideo({ block, palette: p, onLink }) {
|
|
3225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Pressable, { accessibilityRole: "link", accessibilityLabel: block.alt, onPress: () => onLink(block.href), style: ({ pressed }) => [styles2.video, { borderColor: p.border, backgroundColor: p.surface, opacity: pressed ? 0.7 : 1 }], children: [
|
|
3226
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [styles2.play, { color: p.primary }], children: "\u25B6" }),
|
|
3227
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { color: p.primary, fontFamily: p.fontFamily, fontWeight: "600" }, children: block.alt })
|
|
3228
|
+
] });
|
|
3229
|
+
}
|
|
3230
|
+
var PAGE_RATIO = 1 / 1.414;
|
|
3231
|
+
var pageRatio = (p) => p.width && p.height ? p.width / p.height : PAGE_RATIO;
|
|
3232
|
+
function PdfBadge() {
|
|
3233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: styles2.badge, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles2.badgeText, children: "PDF" }) });
|
|
3234
|
+
}
|
|
3235
|
+
function BodyFile({ block, palette: p, onLink }) {
|
|
3236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Pressable, { accessibilityRole: "link", accessibilityLabel: `${block.alt}, PDF`, onPress: () => onLink(block.href), style: ({ pressed }) => [styles2.video, { borderColor: p.border, backgroundColor: p.surface, opacity: pressed ? 0.7 : 1 }], children: [
|
|
3237
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PdfBadge, {}),
|
|
3238
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { numberOfLines: 2, ellipsizeMode: "middle", style: [styles2.flex, { color: p.text, fontFamily: p.fontFamily, fontWeight: "600" }], children: block.alt })
|
|
3239
|
+
] });
|
|
3240
|
+
}
|
|
3241
|
+
function BodyPdf({ block, palette: p, onLink }) {
|
|
3242
|
+
const pages = block.pages ?? [];
|
|
3243
|
+
const [width, setWidth] = (0, import_react.useState)(0);
|
|
3244
|
+
const [index, setIndex] = (0, import_react.useState)(0);
|
|
3245
|
+
const [reading, setReading] = (0, import_react.useState)(false);
|
|
3246
|
+
const height = width ? Math.max(...pages.map((pg) => width / pageRatio(pg))) : 0;
|
|
3247
|
+
const onScroll = (e) => width && setIndex(Math.round(e.nativeEvent.contentOffset.x / width));
|
|
3248
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [styles2.pdf, { borderColor: p.border, backgroundColor: p.surface }], children: [
|
|
3249
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: `Read ${block.alt} full screen`, onPress: () => setReading(true), style: ({ pressed }) => [styles2.pdfHeader, { opacity: pressed ? 0.7 : 1 }], children: [
|
|
3250
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PdfBadge, {}),
|
|
3251
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { numberOfLines: 1, ellipsizeMode: "middle", style: [styles2.flex, { color: p.text, fontFamily: p.fontFamily, fontWeight: "600" }], children: block.alt }),
|
|
3252
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: { color: p.muted, fontSize: 16 }, children: "\u2922" })
|
|
3253
|
+
] }),
|
|
3254
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.pdfPages, onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
|
|
3255
|
+
width > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ScrollView, { horizontal: true, pagingEnabled: true, showsHorizontalScrollIndicator: false, onScroll, scrollEventThrottle: 32, accessibilityLabel: `${block.alt}, page ${index + 1} of ${pages.length}`, children: pages.map((pg, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Pressable, { onPress: () => setReading(true), accessibilityRole: "imagebutton", accessibilityLabel: pg.alt || `Page ${i + 1}`, accessibilityHint: "Opens the document full screen", style: { width, height, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: pg.src }, resizeMode: "contain", style: [styles2.page, { width: Math.min(width, height * pageRatio(pg)), aspectRatio: pageRatio(pg) }] }) }, i)) }),
|
|
3256
|
+
pages.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { pointerEvents: "none", style: styles2.count, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Text, { style: styles2.countText, children: [
|
|
3257
|
+
index + 1,
|
|
3258
|
+
" / ",
|
|
3259
|
+
pages.length
|
|
3260
|
+
] }) })
|
|
3261
|
+
] }),
|
|
3262
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Modal, { visible: reading, animationType: "slide", presentationStyle: "fullScreen", onRequestClose: () => setReading(false), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.reader, children: [
|
|
3263
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.readerBar, children: [
|
|
3264
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { numberOfLines: 1, ellipsizeMode: "middle", style: [styles2.flex, styles2.readerTitle], accessibilityRole: "header", children: block.alt }),
|
|
3265
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Pressable, { accessibilityRole: "link", onPress: () => onLink(block.href), style: styles2.readerBtn, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles2.readerBtnText, children: "Open PDF \u2197" }) }),
|
|
3266
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Pressable, { accessibilityRole: "button", accessibilityLabel: "Close", onPress: () => setReading(false), style: styles2.readerBtn, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: styles2.readerBtnText, children: "Done" }) })
|
|
3267
|
+
] }),
|
|
3268
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ScrollView, { contentContainerStyle: styles2.readerPages, children: pages.map((pg, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Image, { source: { uri: pg.src }, accessible: true, accessibilityLabel: pg.alt || `Page ${i + 1}`, resizeMode: "contain", style: [styles2.readerPage, { aspectRatio: pageRatio(pg) }] }, i)) })
|
|
3269
|
+
] }) })
|
|
3270
|
+
] });
|
|
3271
|
+
}
|
|
2963
3272
|
function RichText({ html, palette: p, onLink, size = 15 }) {
|
|
2964
3273
|
const blocks = (0, import_react.useMemo)(() => parseHtml(html), [html]);
|
|
2965
3274
|
if (!blocks.length) return null;
|
|
2966
3275
|
const base = { color: p.text, fontSize: size, lineHeight: Math.round(size * 1.42), fontFamily: p.fontFamily };
|
|
2967
3276
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: styles2.wrap, children: blocks.map((b, i) => {
|
|
3277
|
+
if (b.kind === "image") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BodyImage, { block: b, palette: p }, i);
|
|
3278
|
+
if (b.kind === "video") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BodyVideo, { block: b, palette: p, onLink }, i);
|
|
3279
|
+
if (b.kind === "pdf") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BodyPdf, { block: b, palette: p, onLink }, i);
|
|
3280
|
+
if (b.kind === "file") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BodyFile, { block: b, palette: p, onLink }, i);
|
|
2968
3281
|
const runs = b.runs.map((r, j) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: runStyle(r, p), onPress: r.href ? () => onLink(r.href) : void 0, accessibilityRole: r.href ? "link" : void 0, children: r.text }, j));
|
|
2969
3282
|
if (b.kind === "list-item") {
|
|
2970
3283
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [styles2.li, { paddingLeft: (b.level - 1) * 14 }], children: [
|
|
@@ -2983,7 +3296,25 @@ var styles2 = import_react_native2.StyleSheet.create({
|
|
|
2983
3296
|
wrap: { gap: 6 },
|
|
2984
3297
|
li: { flexDirection: "row", gap: 6 },
|
|
2985
3298
|
marker: { minWidth: 14 },
|
|
2986
|
-
flex: { flex: 1 }
|
|
3299
|
+
flex: { flex: 1 },
|
|
3300
|
+
image: { width: "100%", borderRadius: 6 },
|
|
3301
|
+
video: { flexDirection: "row", alignItems: "center", gap: 8, paddingVertical: 12, paddingHorizontal: 14, borderWidth: 1, borderRadius: 8 },
|
|
3302
|
+
play: { fontSize: 14 },
|
|
3303
|
+
badge: { backgroundColor: "#e5484d", borderRadius: 4, paddingHorizontal: 5, paddingVertical: 3 },
|
|
3304
|
+
badgeText: { color: "#fff", fontSize: 9, fontWeight: "700", letterSpacing: 0.4 },
|
|
3305
|
+
pdf: { borderWidth: 1, borderRadius: 10, overflow: "hidden" },
|
|
3306
|
+
pdfHeader: { flexDirection: "row", alignItems: "center", gap: 8, minHeight: 44, paddingHorizontal: 12 },
|
|
3307
|
+
pdfPages: { marginHorizontal: 10, marginBottom: 10 },
|
|
3308
|
+
page: { backgroundColor: "#fff", borderRadius: 3 },
|
|
3309
|
+
count: { position: "absolute", right: 8, bottom: 8, backgroundColor: "rgba(17,17,17,0.72)", borderRadius: 999, paddingHorizontal: 8, paddingVertical: 2 },
|
|
3310
|
+
countText: { color: "#fff", fontSize: 11, fontWeight: "500", fontVariant: ["tabular-nums"] },
|
|
3311
|
+
reader: { flex: 1, backgroundColor: "#0b0b0d" },
|
|
3312
|
+
readerBar: { flexDirection: "row", alignItems: "center", gap: 8, paddingTop: import_react_native2.Platform.OS === "ios" ? 52 : 12, paddingBottom: 10, paddingHorizontal: 16 },
|
|
3313
|
+
readerTitle: { color: "#fff", fontSize: 16, fontWeight: "600" },
|
|
3314
|
+
readerBtn: { minHeight: 36, justifyContent: "center", paddingHorizontal: 12, borderRadius: 8, backgroundColor: "rgba(255,255,255,0.12)" },
|
|
3315
|
+
readerBtnText: { color: "#fff", fontWeight: "600" },
|
|
3316
|
+
readerPages: { gap: 12, paddingHorizontal: 12, paddingBottom: 32 },
|
|
3317
|
+
readerPage: { width: "100%", backgroundColor: "#fff", borderRadius: 2 }
|
|
2987
3318
|
});
|
|
2988
3319
|
|
|
2989
3320
|
// src/ui/Checklist.tsx
|
|
@@ -3333,18 +3664,15 @@ function Help({ store, client, palette: p }) {
|
|
|
3333
3664
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { accessibilityRole: "header", style: [styles4.sectionTitle, { color: p.muted }], children: title.toUpperCase() }),
|
|
3334
3665
|
children
|
|
3335
3666
|
] }, title);
|
|
3336
|
-
const
|
|
3337
|
-
const
|
|
3667
|
+
const audiences = client.getAudienceIds();
|
|
3668
|
+
const sections = resourceCenterSections(articles?.collections ?? [], articles?.articles ?? [], audiences);
|
|
3669
|
+
const listed = results?.filter((a) => isArticleListed(articles?.collections ?? [], a, audiences));
|
|
3338
3670
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.ScrollView, { contentContainerStyle: styles4.content, keyboardShouldPersistTaps: "handled", children: [
|
|
3339
3671
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.TextInput, { value: q, onChangeText: setQ, placeholder: "Search articles", placeholderTextColor: p.muted, accessibilityLabel: "Search help articles", returnKeyType: "search", style: [styles4.search, { color: p.text, backgroundColor: p.surface, borderRadius: Math.min(10, p.radius) }] }),
|
|
3340
|
-
|
|
3672
|
+
listed ? section(`Results for \u201C${q.trim()}\u201D`, listed.length ? listed.map((a) => row(a.id, a.title, a.summary, () => open(a))) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.Text, { style: [styles4.rowSub, { color: p.muted }], children: "No articles found." })) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
3341
3673
|
recommended.length ? section("Recommended", recommended.map((g) => row(g.id, g.name, void 0, () => store.startGuide(g.key), "\u25B6"))) : null,
|
|
3342
3674
|
!articles ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native4.ActivityIndicator, { color: p.muted }) : null,
|
|
3343
|
-
|
|
3344
|
-
const items = (articles?.articles ?? []).filter((a) => a.collectionId === c.id);
|
|
3345
|
-
return items.length ? section(c.name, items.map((a) => row(a.id, a.title, a.summary, () => open(a)))) : null;
|
|
3346
|
-
}),
|
|
3347
|
-
loose.length ? section("Articles", loose.map((a) => row(a.id, a.title, a.summary, () => open(a)))) : null,
|
|
3675
|
+
sections.map((s) => section(s.collection ? s.path.join(" \u203A ") : "Articles", s.articles.map((a) => row(a.id, a.title, a.summary, () => open(a))))),
|
|
3348
3676
|
rc?.faqs.length ? section(
|
|
3349
3677
|
"FAQ",
|
|
3350
3678
|
rc.faqs.map((f) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native4.View, { style: [styles4.row, styles4.faq, { borderColor: p.border }], children: [
|
|
@@ -3475,8 +3803,9 @@ function ResourceCenter({ client, palette: p, open, topInset, bottomInset }) {
|
|
|
3475
3803
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { accessibilityRole: "header", style: [styles5.sectionTitle, { color: p.muted }], children: title.toUpperCase() }),
|
|
3476
3804
|
children
|
|
3477
3805
|
] }, title);
|
|
3478
|
-
const
|
|
3479
|
-
const
|
|
3806
|
+
const audiences = client.getAudienceIds();
|
|
3807
|
+
const sections = resourceCenterSections(rc.collections, rc.articles, audiences);
|
|
3808
|
+
const listed = results?.filter((a) => isArticleListed(rc.collections, a, audiences));
|
|
3480
3809
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Modal, { visible: open, animationType: "slide", presentationStyle: import_react_native5.Platform.OS === "ios" ? "pageSheet" : "fullScreen", onRequestClose: () => article ? setArticle(null) : close(), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles5.sheet, { backgroundColor: p.background, paddingTop: import_react_native5.Platform.OS === "ios" ? 8 : topInset }], children: [
|
|
3481
3810
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles5.header, { borderColor: p.border }], children: [
|
|
3482
3811
|
article ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Pressable, { accessibilityRole: "button", accessibilityLabel: "Back", onPress: () => setArticle(null), hitSlop: 10, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles5.back, { color: p.primary }], children: "\u2039 Back" }) }) : null,
|
|
@@ -3500,17 +3829,13 @@ function ResourceCenter({ client, palette: p, open, topInset, bottomInset }) {
|
|
|
3500
3829
|
style: [styles5.search, { color: p.text, backgroundColor: p.surface, borderRadius: Math.min(10, p.radius) }]
|
|
3501
3830
|
}
|
|
3502
3831
|
),
|
|
3503
|
-
|
|
3832
|
+
listed ? section(
|
|
3504
3833
|
`Results for \u201C${query.trim()}\u201D`,
|
|
3505
|
-
|
|
3834
|
+
listed.length ? listed.map((a) => row(a.id, a.title, a.summary, () => openArticle(a))) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native5.Text, { style: [styles5.rowSub, { color: p.muted }], children: "No articles found." })
|
|
3506
3835
|
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
3507
3836
|
recommended.length ? section("Recommended", recommended.map((g) => row(g.id, g.name, void 0, () => (close(), client.startGuide(g.id)), "\u25B6"))) : null,
|
|
3508
3837
|
checklists.length ? section("Checklists", checklists.map((g) => row(g.id, g.name, void 0, () => (close(), client.openChecklist(g.id)), "\u2611"))) : null,
|
|
3509
|
-
|
|
3510
|
-
const items = rc.articles.filter((a) => a.collectionId === c.id);
|
|
3511
|
-
return items.length ? section(c.name, items.map((a) => row(a.id, a.title, a.summary, () => openArticle(a)))) : null;
|
|
3512
|
-
}),
|
|
3513
|
-
loose.length ? section("Articles", loose.map((a) => row(a.id, a.title, a.summary, () => openArticle(a)))) : null,
|
|
3838
|
+
sections.map((s) => section(s.collection ? s.path.join(" \u203A ") : "Articles", s.articles.map((a) => row(a.id, a.title, a.summary, () => openArticle(a))))),
|
|
3514
3839
|
rc.faqs.length ? section(
|
|
3515
3840
|
"FAQ",
|
|
3516
3841
|
rc.faqs.map((f) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native5.View, { style: [styles5.row, styles5.faq, { borderColor: p.border }], children: [
|